mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-18 11:45:11 +08:00
For certain inserts on a distributed hypertable, e.g., involving CTEs and upserts, plans can be generated that weren't properly handled by the DataNodeCopy and DataNodeDispatch execution nodes. In particular, the nodes expect ChunkDispatch as a child node, but PostgreSQL can sometimes insert a Result node above ChunkDispatch, causing the crash. Further, behavioral changes in PG14 also caused the DataNodeCopy node to sometimes wrongly believe a RETURNING clause was present. The check for returning clauses has been updated to fix this issue. Fixes #4339
59 lines
1.6 KiB
PL/PgSQL
59 lines
1.6 KiB
PL/PgSQL
-- This file and its contents are licensed under the Timescale License.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-TIMESCALE for a copy of the license.
|
|
|
|
-- Test DataNodeScan with subquery with one-time filter
|
|
SELECT
|
|
id
|
|
FROM
|
|
insert_test
|
|
WHERE
|
|
NULL::int2 >= NULL::int2 OR
|
|
EXISTS (SELECT 1 from dist_chunk_copy WHERE insert_test.id IS NOT NULL)
|
|
ORDER BY id;
|
|
|
|
-- Test query that inserts a Result node between ChunkDispatch and
|
|
-- DataNodeDispatch/DataNodeCopy. Fix for bug
|
|
-- https://github.com/timescale/timescaledb/issues/4339
|
|
|
|
SET timescaledb.enable_distributed_insert_with_copy=false;
|
|
|
|
BEGIN;
|
|
WITH upsert AS (
|
|
UPDATE matches
|
|
SET day = day - 1
|
|
WHERE location = 'old trafford'
|
|
RETURNING *
|
|
) INSERT INTO matches (day, location, team1, team2)
|
|
SELECT 9, 'old trafford', 'MNU', 'MNC'
|
|
WHERE NOT EXISTS (SELECT 1 FROM upsert);
|
|
SELECT * FROM matches ORDER BY 1,2,3,4;
|
|
ROLLBACK;
|
|
|
|
SET timescaledb.enable_distributed_insert_with_copy=true;
|
|
|
|
BEGIN;
|
|
WITH upsert AS (
|
|
UPDATE matches
|
|
SET day = day - 1
|
|
WHERE location = 'old trafford'
|
|
RETURNING *
|
|
) INSERT INTO matches (day, location, team1, team2)
|
|
SELECT 9, 'old trafford', 'MNU', 'MNC'
|
|
WHERE NOT EXISTS (SELECT 1 FROM upsert);
|
|
SELECT * FROM matches ORDER BY 1,2,3,4;
|
|
ROLLBACK;
|
|
|
|
-- Reference. The two queries above should be like this one:
|
|
BEGIN;
|
|
WITH upsert AS (
|
|
UPDATE matches_reference
|
|
SET day = day - 1
|
|
WHERE location = 'old trafford'
|
|
RETURNING *
|
|
) INSERT INTO matches_reference (day, location, team1, team2)
|
|
SELECT 9, 'old trafford', 'MNU', 'MNC'
|
|
WHERE NOT EXISTS (SELECT 1 FROM upsert);
|
|
SELECT * FROM matches_reference ORDER BY 1,2,3,4;
|
|
ROLLBACK;
|