Skip to content

Commit 0428c8a

Browse files
authored
Merge pull request #1189 from oasisprotocol/ptrus/fix/delegation-shares-negative
analyzer/queries: avoid uint_numeric check failure on negative shares during upsert
2 parents 67de4db + 48938e9 commit 0428c8a

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

.changelog/1189.bugfix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
analyzer/queries: avoid uint_numeric check failure on negative shares

analyzer/queries/queries.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -764,16 +764,30 @@ var (
764764
SET shares = $4`
765765

766766
RuntimeConsensusAccountDelegationUpsert = `
767-
INSERT INTO chain.runtime_accounts_delegations AS old (runtime, delegator, delegatee, shares)
768-
VALUES ($1, $2, $3, $4)
769-
ON CONFLICT (runtime, delegator, delegatee) DO UPDATE
770-
SET shares = old.shares + $4`
767+
-- Update-first pattern to avoid uint_numeric check failure on negative deltas in shares.
768+
-- Regular UPSERT casts shares from VALUES() before conflict check, causing premature failure.
769+
WITH up AS (
770+
UPDATE chain.runtime_accounts_delegations
771+
SET shares = shares + $4::numeric
772+
WHERE runtime = $1 AND delegator = $2 AND delegatee = $3
773+
RETURNING 1
774+
)
775+
INSERT INTO chain.runtime_accounts_delegations (runtime, delegator, delegatee, shares)
776+
SELECT $1, $2, $3, ($4)::uint_numeric
777+
WHERE NOT EXISTS (SELECT 1 FROM up)`
771778

772779
RuntimeConsensusAccountDebondingDelegationUpsert = `
773-
INSERT INTO chain.runtime_accounts_debonding_delegations AS old (runtime, delegator, delegatee, debond_end, shares)
774-
VALUES ($1, $2, $3, $4, $5)
775-
ON CONFLICT (runtime, delegator, delegatee, debond_end) DO UPDATE
776-
SET shares = old.shares + $5`
780+
-- Update-first pattern to avoid uint_numeric check failure on negative deltas in shares.
781+
-- Regular UPSERT casts shares from VALUES() before conflict check, causing premature failure.
782+
WITH up AS (
783+
UPDATE chain.runtime_accounts_debonding_delegations
784+
SET shares = shares + $5::numeric
785+
WHERE runtime = $1 AND delegator = $2 AND delegatee = $3 AND debond_end = $4
786+
RETURNING 1
787+
)
788+
INSERT INTO chain.runtime_accounts_debonding_delegations (runtime, delegator, delegatee, debond_end, shares)
789+
SELECT $1, $2, $3, $4, ($5)::uint_numeric
790+
WHERE NOT EXISTS (SELECT 1 FROM up)`
777791

778792
// The NULL check `debond_end IS NULL` is included to handle pre-v0.15.0 events,
779793
// where debond_end may be NULL. This ensures backward compatibility with older data.

0 commit comments

Comments
 (0)