1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
# name: test/sql/parallelism/interquery/concurrent_checkpoint_single_updater.test_slow
# description: Concurrent checkpoint with single updater
# group: [interquery]
load __TEST_DIR__/concurrent_checkpoint.db
statement ok
CREATE TABLE accounts(id INTEGER, money INTEGER)
statement ok
INSERT INTO accounts SELECT i AS id, 10 AS money FROM range(10) t(i)
concurrentforeach thread updater checkpointer
loop x 0 1000
# the total balance should remain constant regardless of updates and checkpoints
onlyif thread=checkpointer
query I
SELECT SUM(money) FROM accounts
----
100
onlyif thread=checkpointer
statement ok
FORCE CHECKPOINT
endloop
loop x 0 200
# generate a random transfer (random from / to / amount)
onlyif thread=updater
statement ok
SET VARIABLE from_account = (RANDOM() * 9)::UBIGINT;
onlyif thread=updater
statement ok
SET VARIABLE to_account = (SELECT * FROM range(10) t(i) WHERE i <> getvariable('from_account') ORDER BY RANDOM() LIMIT 1)
onlyif thread=updater
statement ok
SET VARIABLE amount = (RANDOM() * 10)::UBIGINT
# perform the transfer
onlyif thread=updater
statement ok
BEGIN TRANSACTION
# store how much money the accounts had before
onlyif thread=updater
statement ok
SET VARIABLE prev_money = (SELECT {'from_money': MIN(money) FILTER (WHERE id=getvariable('from_account')), 'to_money': MIN(money) FILTER (WHERE id=getvariable('to_account'))} FROM accounts)
onlyif thread=updater
query I
UPDATE accounts SET money = money - getvariable('amount') WHERE id=getvariable('from_account')
----
1
onlyif thread=updater
query I
UPDATE accounts SET money = money + getvariable('amount') WHERE id=getvariable('to_account')
----
1
# verify the update went through correctly
onlyif thread=updater
query I
SELECT CASE
WHEN t.s.from_money = (getvariable('prev_money')).from_money - getvariable('amount') AND t.s.to_money = (getvariable('prev_money')).to_money + getvariable('amount')
THEN NULL
ELSE {'prev': getvariable('prev_money'), 'current': t.s, 'amount': getvariable('amount'), 'from_account': getvariable('from_account'), 'to_account': getvariable('to_account')}
END
FROM (SELECT {'from_money': MIN(money) FILTER (WHERE id=getvariable('from_account')), 'to_money': MIN(money) FILTER (WHERE id=getvariable('to_account'))} s FROM accounts) t
----
NULL
onlyif thread=updater
statement ok
COMMIT
endloop
endloop
query I
SELECT SUM(money) FROM accounts
----
100
|