# This test verifies INSERT ON CONFLICT DO UPDATE behavior on partitioned # tables concurrent with REINDEX CONCURRENTLY. # # - s1: UPSERT a tuple # - s2: UPSERT the same tuple # - s3: concurrently REINDEX the primary key index # # - s4: controls concurrency via injection points setup { CREATE EXTENSION injection_points; CREATE SCHEMA test; CREATE TABLE test.tbl(i int primary key, updated_at timestamp) PARTITION BY RANGE (i); CREATE TABLE test.tbl_partition PARTITION OF test.tbl FOR VALUES FROM (0) TO (10000) WITH (parallel_workers = 0); } teardown { DROP SCHEMA test CASCADE; DROP EXTENSION injection_points; } session s1 setup { SELECT injection_points_set_local(); SELECT injection_points_attach('check-exclusion-or-unique-constraint-no-conflict', 'wait'); } step s1_start_upsert { INSERT INTO test.tbl VALUES (13, now()) ON CONFLICT (i) DO UPDATE SET updated_at = now(); } session s2 setup { SELECT injection_points_set_local(); SELECT injection_points_attach('exec-insert-before-insert-speculative', 'wait'); } step s2_start_upsert { INSERT INTO test.tbl VALUES (13, now()) ON CONFLICT (i) DO UPDATE SET updated_at = now(); } session s3 setup { SELECT injection_points_set_local(); } step s3_setup_wait_before_set_dead { SELECT injection_points_attach('reindex-relation-concurrently-before-set-dead', 'wait'); } step s3_setup_wait_before_swap { SELECT injection_points_attach('reindex-relation-concurrently-before-swap', 'wait'); } step s3_start_reindex { REINDEX INDEX CONCURRENTLY test.tbl_partition_pkey; } session s4 step s4_wakeup_to_swap { SELECT injection_points_detach('reindex-relation-concurrently-before-swap'); SELECT injection_points_wakeup('reindex-relation-concurrently-before-swap'); } step s4_wakeup_s1 { SELECT injection_points_detach('check-exclusion-or-unique-constraint-no-conflict'); SELECT injection_points_wakeup('check-exclusion-or-unique-constraint-no-conflict'); } step s4_wakeup_s2 { SELECT injection_points_detach('exec-insert-before-insert-speculative'); SELECT injection_points_wakeup('exec-insert-before-insert-speculative'); } step s4_wakeup_to_set_dead { SELECT injection_points_detach('reindex-relation-concurrently-before-set-dead'); SELECT injection_points_wakeup('reindex-relation-concurrently-before-set-dead'); } permutation s3_setup_wait_before_set_dead s3_start_reindex(s1_start_upsert, s2_start_upsert) s1_start_upsert(s4_wakeup_s2) s4_wakeup_to_set_dead s2_start_upsert(s1_start_upsert) s4_wakeup_s1 s4_wakeup_s2 permutation s3_setup_wait_before_swap s3_start_reindex(s1_start_upsert, s2_start_upsert) s1_start_upsert(s4_wakeup_s2) s4_wakeup_to_swap s2_start_upsert(s1_start_upsert) s4_wakeup_s2 s4_wakeup_s1 permutation s3_setup_wait_before_set_dead s3_start_reindex(s1_start_upsert, s2_start_upsert) s1_start_upsert(s4_wakeup_s2) s2_start_upsert(s1_start_upsert) s4_wakeup_s1 s4_wakeup_to_set_dead s4_wakeup_s2