Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change SQL statement InsertNewAsset into an upsert. #684

Closed
wants to merge 2 commits into from

Conversation

ffranr
Copy link
Contributor

@ffranr ffranr commented Nov 17, 2023

This PR changes an asset insert SQL query into an upsert. InsertNewAsset -> UpsertAsset. This should fix #665 at the DB level. But we should also apply a fix to the custodian.

I think that this PR sucessfully adds a new constraint to the assets SQL table. It doesn't remove the old constraint. But I don't think we need to because the old unique constraint didn't actually constrain anything. It contained the row ID primary key so it was basically a NOP. Am I right?

I'm not sure if I've implemented the assets table migration correctly. What happens to those rows which are in tables with foreign key relationships to the assets table?

Even if this PR works. There's a bunch more things that we need to do to make tapd robust to this problem:

  • Unit tests for the UpsertAsset query.
  • Stopping the custodian from even attempting a duplicate insert.

@ffranr ffranr marked this pull request as draft November 17, 2023 18:31
@ffranr ffranr force-pushed the balance-bug-db-query-fix branch from 66a73c2 to f10120c Compare November 17, 2023 18:34
@ffranr ffranr changed the title Balance bug db asset insert query fix Change SQL statement InsertNewAsset into an upsert. Nov 17, 2023
@ffranr ffranr marked this pull request as ready for review November 17, 2023 19:08
@ffranr
Copy link
Contributor Author

ffranr commented Nov 20, 2023

A less risk solution, please consider first: #687

@ffranr ffranr marked this pull request as draft November 20, 2023 12:40
@dstadulis dstadulis added this to the v0.3.2 milestone Nov 20, 2023
@ffranr ffranr removed this from the v0.3.2 milestone Nov 20, 2023
@ffranr ffranr linked an issue Nov 21, 2023 that may be closed by this pull request
@guggero guggero self-requested a review November 27, 2023 16:51
@ffranr ffranr force-pushed the balance-bug-db-query-fix branch from 98c2233 to ec00e24 Compare November 27, 2023 21:38
@ffranr
Copy link
Contributor Author

ffranr commented Nov 27, 2023

I've just rebased and bumped SQL migration numbers. The itest was removed from this PR because it's already merged.

Copy link
Member

@guggero guggero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first pass. I think the approach is correct, but might need some more involved SQL magic to get rid of the old unique key.

@@ -0,0 +1,31 @@
-- We will apply a new unique constraint on the assets table. This constraint
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we should add a comment to the .down.sql file that it's empty on purpose.

-- This is the row number of the row within the set of rows that violate
-- the constraint. We will delete all rows with a row number greater
-- than 1.
ROW_NUMBER() OVER (PARTITION BY anchor_utxo_id, genesis_id, script_key_id ORDER BY asset_id) AS row_num
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now why we'd want to have a way to test migration scripts...
I think this probably works, but we definitely need to make sure it does the correct thing for both Postgres and SQLite.

);

-- Create a unique index on the new table
CREATE UNIQUE INDEX assets_uniqueness_index_anchor_utxo_id_genesis_id_script_key_id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a way to remove the index created by the previous UNIQUE(asset_id, genesis_id, script_key_id) part? I guess that's probably dependent on the actual DB implementation.
This is likely a downside of using the "inline" unique key creation, that it doesn't have a name and therefore can't easily be updated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think I google that before at some point... And if I remember correctly, we basically need to re-create the table to get rid of the original unique constraint. But I think we'd probably want to do that, as otherwise this is an expensive but useless index we're carrying along.
IIRC this is how you replace a table "correctly":

  1. CREATE TABLE assets_tmp ... (full definition, but without the inline UNIQUE constraint)
  2. INSERT INTO assets_tmp AS SELECT * from assets
  3. Alter any foreign keys that point to the old assets table
  4. DROP TABLE assets
  5. ALTER TABLE assets_tmp RENAME TO assets

@ffranr
Copy link
Contributor Author

ffranr commented Dec 12, 2023

Now that the db migration work has been merged. We should test this PR using that framework.

@GeorgeTsagk
Copy link
Member

@ffranr is this PR still in progress or should we close?

@ffranr
Copy link
Contributor Author

ffranr commented Mar 12, 2024

I don't think this is worth doing right now. Perhaps in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

[bug]: Troubleshoot discrepancy between command results: asset balance and assets list
4 participants