Skip to content

Commit

Permalink
Fix EXPLAIN for compressed DML
Browse files Browse the repository at this point in the history
EXPLAIN ANALYZE for compressed DML would error out with `bogus varno`
error because we would modify the original expressions of the plan
that were still referenced in nodes instead of adjusting copies and
using those copies in our internal scans.
  • Loading branch information
svenklemm committed Oct 18, 2023
1 parent 5f5f519 commit 8f3bb0b
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
1 change: 1 addition & 0 deletions .unreleased/pr_6210
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixes: #6210 Fix EXPLAIN ANALYZE for compressed DML
5 changes: 1 addition & 4 deletions tsl/src/compression/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -2756,9 +2756,7 @@ fill_predicate_context(Chunk *ch, List *predicates, List **filters, List **index
ListCell *lc;
foreach (lc, predicates)
{
Node *node = lfirst(lc);
if (node == NULL)
continue;
Node *node = copyObject(lfirst(lc));

Var *var;
char *column_name;
Expand Down Expand Up @@ -3367,7 +3365,6 @@ decompress_chunk_walker(PlanState *ps, struct decompress_chunk_context *ctx)
case T_TidScanState:
case T_TidRangeScanState:
{
/* We copy so we can always just free the predicates */
predicates = list_copy(ps->plan->qual);
needs_decompression = true;
break;
Expand Down
61 changes: 61 additions & 0 deletions tsl/test/shared/expected/decompress_tracking.out
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ QUERY PLAN
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_2 (actual rows=20 loops=1)
(10 rows)

BEGIN; :EXPLAIN_ANALYZE UPDATE decompress_tracking SET value = value + 3 WHERE device = 'd2'; ROLLBACK;
QUERY PLAN
Custom Scan (HypertableModify) (actual rows=0 loops=1)
Batches decompressed: 2
Tuples decompressed: 20
-> Update on decompress_tracking (actual rows=0 loops=1)
Update on _hyper_X_X_chunk decompress_tracking_1
Update on _hyper_X_X_chunk decompress_tracking_2
-> Result (actual rows=20 loops=1)
-> Append (actual rows=20 loops=1)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_1 (actual rows=15 loops=1)
Filter: (device = 'd2'::text)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_2 (actual rows=5 loops=1)
Filter: (device = 'd2'::text)
(12 rows)

BEGIN; :EXPLAIN_ANALYZE DELETE FROM decompress_tracking; ROLLBACK;
QUERY PLAN
Custom Scan (HypertableModify) (actual rows=0 loops=1)
Expand All @@ -58,6 +74,21 @@ QUERY PLAN
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_2 (actual rows=20 loops=1)
(9 rows)

BEGIN; :EXPLAIN_ANALYZE DELETE FROM decompress_tracking WHERE device = 'd3'; ROLLBACK;
QUERY PLAN
Custom Scan (HypertableModify) (actual rows=0 loops=1)
Batches decompressed: 2
Tuples decompressed: 30
-> Delete on decompress_tracking (actual rows=0 loops=1)
Delete on _hyper_X_X_chunk decompress_tracking_1
Delete on _hyper_X_X_chunk decompress_tracking_2
-> Append (actual rows=30 loops=1)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_1 (actual rows=15 loops=1)
Filter: (device = 'd3'::text)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_2 (actual rows=15 loops=1)
Filter: (device = 'd3'::text)
(11 rows)

BEGIN; :EXPLAIN_ANALYZE INSERT INTO decompress_tracking SELECT '2020-01-01 1:30','d1',random(); ROLLBACK;
QUERY PLAN
Custom Scan (HypertableModify) (actual rows=0 loops=1)
Expand Down Expand Up @@ -97,4 +128,34 @@ QUERY PLAN
-> Values Scan on "*VALUES*" (actual rows=2 loops=1)
(6 rows)

-- test prepared statements EXPLAIN still works after execution
SET plan_cache_mode TO force_generic_plan;
PREPARE p1 AS UPDATE decompress_tracking SET value = value + 3 WHERE device = 'd1';
BEGIN; EXPLAIN EXECUTE p1; EXECUTE p1; EXPLAIN EXECUTE p1; ROLLBACK;
QUERY PLAN
Custom Scan (HypertableModify) (cost=0.00..70.83 rows=433 width=18)
-> Update on decompress_tracking (cost=0.00..70.83 rows=433 width=18)
Update on _hyper_X_X_chunk decompress_tracking_1
Update on _hyper_X_X_chunk decompress_tracking_2
-> Result (cost=0.00..70.83 rows=433 width=18)
-> Append (cost=0.00..65.42 rows=433 width=18)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_1 (cost=0.00..31.62 rows=432 width=18)
Filter: (device = 'd1'::text)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_2 (cost=0.00..31.62 rows=1 width=18)
Filter: (device = 'd1'::text)
(10 rows)

QUERY PLAN
Custom Scan (HypertableModify) (cost=0.00..70.83 rows=433 width=18)
-> Update on decompress_tracking (cost=0.00..70.83 rows=433 width=18)
Update on _hyper_X_X_chunk decompress_tracking_1
Update on _hyper_X_X_chunk decompress_tracking_2
-> Result (cost=0.00..70.83 rows=433 width=18)
-> Append (cost=0.00..65.42 rows=433 width=18)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_1 (cost=0.00..31.62 rows=432 width=18)
Filter: (device = 'd1'::text)
-> Seq Scan on _hyper_X_X_chunk decompress_tracking_2 (cost=0.00..31.62 rows=1 width=18)
Filter: (device = 'd1'::text)
(10 rows)

DROP TABLE decompress_tracking;
7 changes: 7 additions & 0 deletions tsl/test/shared/sql/decompress_tracking.sql
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,17 @@ SELECT count(compress_chunk(ch)) FROM show_chunks('decompress_tracking') ch;
:EXPLAIN UPDATE decompress_tracking SET value = value + 3;

BEGIN; :EXPLAIN_ANALYZE UPDATE decompress_tracking SET value = value + 3; ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE UPDATE decompress_tracking SET value = value + 3 WHERE device = 'd2'; ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE DELETE FROM decompress_tracking; ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE DELETE FROM decompress_tracking WHERE device = 'd3'; ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE INSERT INTO decompress_tracking SELECT '2020-01-01 1:30','d1',random(); ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE INSERT INTO decompress_tracking SELECT '2020-01-01','d2',random(); ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE INSERT INTO decompress_tracking SELECT '2020-01-01','d4',random(); ROLLBACK;
BEGIN; :EXPLAIN_ANALYZE INSERT INTO decompress_tracking (VALUES ('2020-01-01 1:30','d1',random()),('2020-01-01 1:30','d2',random())); ROLLBACK;

-- test prepared statements EXPLAIN still works after execution
SET plan_cache_mode TO force_generic_plan;
PREPARE p1 AS UPDATE decompress_tracking SET value = value + 3 WHERE device = 'd1';
BEGIN; EXPLAIN EXECUTE p1; EXECUTE p1; EXPLAIN EXECUTE p1; ROLLBACK;

DROP TABLE decompress_tracking;

0 comments on commit 8f3bb0b

Please sign in to comment.