diff --git a/.unreleased/pr_6869 b/.unreleased/pr_6869 new file mode 100644 index 00000000000..20a0af6c1ef --- /dev/null +++ b/.unreleased/pr_6869 @@ -0,0 +1 @@ +Fixes: #6869 Fix compressed DML with constraints of form value OP column diff --git a/tsl/src/compression/compression.c b/tsl/src/compression/compression.c index 33c1d7ad440..836c77b396a 100644 --- a/tsl/src/compression/compression.c +++ b/tsl/src/compression/compression.c @@ -2553,6 +2553,7 @@ fill_predicate_context(Chunk *ch, CompressionSettings *settings, List *predicate case T_OpExpr: { OpExpr *opexpr = (OpExpr *) node; + Oid opno = opexpr->opno; RegProcedure opcode = opexpr->opfuncid; Oid collation = opexpr->inputcollid; Expr *leftop, *rightop; @@ -2575,6 +2576,12 @@ fill_predicate_context(Chunk *ch, CompressionSettings *settings, List *predicate { var = (Var *) rightop; arg_value = (Const *) leftop; + opno = get_commutator(opno); + if (!OidIsValid(opno)) + continue; + opcode = get_opcode(opno); + if (!OidIsValid(opcode)) + continue; } else continue; @@ -2584,7 +2591,7 @@ fill_predicate_context(Chunk *ch, CompressionSettings *settings, List *predicate continue; column_name = get_attname(ch->table_id, var->varattno, false); TypeCacheEntry *tce = lookup_type_cache(var->vartype, TYPECACHE_BTREE_OPFAMILY); - int op_strategy = get_op_opfamily_strategy(opexpr->opno, tce->btree_opf); + int op_strategy = get_op_opfamily_strategy(opno, tce->btree_opf); if (ts_array_is_member(settings->fd.segmentby, column_name)) { switch (op_strategy) diff --git a/tsl/test/expected/compression_update_delete.out b/tsl/test/expected/compression_update_delete.out index 559d1aeb4c2..517e6922a30 100644 --- a/tsl/test/expected/compression_update_delete.out +++ b/tsl/test/expected/compression_update_delete.out @@ -2944,3 +2944,106 @@ EXPLAIN (analyze, timing off, costs off, summary off) DELETE FROM test_meta_filt Rows Removed by Filter: 10 (8 rows) +-- test commutator handling in compressed dml constraints +CREATE TABLE test_commutator(time timestamptz NOT NULL, device text); +SELECT table_name FROM create_hypertable('test_commutator', 'time'); + table_name +----------------- + test_commutator +(1 row) + +INSERT INTO test_commutator SELECT '2020-01-01', 'a'; +INSERT INTO test_commutator SELECT '2020-01-01', 'b'; +INSERT INTO test_commutator SELECT '2020-01-01', 'c'; +ALTER TABLE test_commutator SET (timescaledb.compress, timescaledb.compress_segmentby='device'); +NOTICE: default order by for hypertable "test_commutator" is set to ""time" DESC" +SELECT compress_chunk(show_chunks('test_commutator')); + compress_chunk +------------------------------------------ + _timescaledb_internal._hyper_39_79_chunk +(1 row) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'a' = device; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 1 + Tuples decompressed: 1 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=1 loops=1) + Filter: ('a'::text = device) +(7 rows) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE device < 'c' ; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 2 + Tuples decompressed: 2 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=2 loops=1) + Filter: (device < 'c'::text) +(7 rows) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'c' > device; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 2 + Tuples decompressed: 2 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=2 loops=1) + Filter: ('c'::text > device) +(7 rows) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'c' >= device; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 3 + Tuples decompressed: 3 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=3 loops=1) + Filter: ('c'::text >= device) +(7 rows) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE device > 'b'; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 1 + Tuples decompressed: 1 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=1 loops=1) + Filter: (device > 'b'::text) +(7 rows) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'b' < device; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 1 + Tuples decompressed: 1 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=1 loops=1) + Filter: ('b'::text < device) +(7 rows) + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'b' <= device; ROLLBACK; + QUERY PLAN +-------------------------------------------------------------------------------------- + Custom Scan (HypertableModify) (actual rows=0 loops=1) + Batches decompressed: 2 + Tuples decompressed: 2 + -> Delete on test_commutator (actual rows=0 loops=1) + Delete on _hyper_39_79_chunk test_commutator_1 + -> Seq Scan on _hyper_39_79_chunk test_commutator_1 (actual rows=2 loops=1) + Filter: ('b'::text <= device) +(7 rows) + diff --git a/tsl/test/sql/compression_update_delete.sql b/tsl/test/sql/compression_update_delete.sql index 4eb7a1a83fd..5553ebc94b3 100644 --- a/tsl/test/sql/compression_update_delete.sql +++ b/tsl/test/sql/compression_update_delete.sql @@ -1493,3 +1493,21 @@ SELECT compress_chunk(show_chunks('test_meta_filters')); EXPLAIN (analyze, timing off, costs off, summary off) DELETE FROM test_meta_filters WHERE device = 'd1' AND metric = 'm1' AND v1 < 100; +-- test commutator handling in compressed dml constraints +CREATE TABLE test_commutator(time timestamptz NOT NULL, device text); +SELECT table_name FROM create_hypertable('test_commutator', 'time'); +INSERT INTO test_commutator SELECT '2020-01-01', 'a'; +INSERT INTO test_commutator SELECT '2020-01-01', 'b'; +INSERT INTO test_commutator SELECT '2020-01-01', 'c'; + +ALTER TABLE test_commutator SET (timescaledb.compress, timescaledb.compress_segmentby='device'); +SELECT compress_chunk(show_chunks('test_commutator')); + +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'a' = device; ROLLBACK; +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE device < 'c' ; ROLLBACK; +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'c' > device; ROLLBACK; +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'c' >= device; ROLLBACK; +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE device > 'b'; ROLLBACK; +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'b' < device; ROLLBACK; +BEGIN; EXPLAIN (costs off, timing off, summary off, analyze) DELETE FROM test_commutator WHERE 'b' <= device; ROLLBACK; +