mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-26 08:41:09 +08:00
Fix segfault in UNION queries with top-level ordering
We can't just filter the equivalence member based on em_is_child as our hypertable might not be top-level equivalence member.
This commit is contained in:
parent
c4656f7604
commit
180c7be7bd
1
.unreleased/pr_6957
Normal file
1
.unreleased/pr_6957
Normal file
@ -0,0 +1 @@
|
||||
Fixes: #6957 Fix segfault in UNION queries with ordering on compressed chunks
|
@ -195,7 +195,7 @@ build_compressed_scan_pathkeys(SortInfo *sort_info, PlannerInfo *root, List *chu
|
||||
* already refers a compressed column, it is a bug. See
|
||||
* build_sortinfo().
|
||||
*/
|
||||
Assert(compressed_em != NULL);
|
||||
Ensure(compressed_em, "corresponding equivalence member not found");
|
||||
|
||||
required_compressed_pathkeys = lappend(required_compressed_pathkeys, pk);
|
||||
|
||||
@ -1482,17 +1482,6 @@ add_segmentby_to_equivalence_class(PlannerInfo *root, EquivalenceClass *cur_ec,
|
||||
Var *var;
|
||||
Assert(!bms_overlap(cur_em->em_relids, info->compressed_rel->relids));
|
||||
|
||||
/*
|
||||
* We want to base our equivalence member on the hypertable equivalence
|
||||
* member, not on the uncompressed chunk one, because the latter is
|
||||
* marked as child itself. This is mostly relevant for PG16 where we
|
||||
* have to specify a parent for the newly created equivalence member.
|
||||
*/
|
||||
if (cur_em->em_is_child)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only consider EquivalenceMembers that are Vars, possibly with RelabelType, of the
|
||||
* uncompressed chunk */
|
||||
var = (Var *) cur_em->em_expr;
|
||||
@ -1501,6 +1490,13 @@ add_segmentby_to_equivalence_class(PlannerInfo *root, EquivalenceClass *cur_ec,
|
||||
if (!(var && IsA(var, Var)))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* We want to base our equivalence member on the hypertable equivalence
|
||||
* member, not on the uncompressed chunk one. We can't just check for
|
||||
* em_is_child though because the hypertable might be a child itself and not
|
||||
* a top-level EquivalenceMember. This is mostly relevant for PG16+ where
|
||||
* we have to specify a parent for the newly created equivalence member.
|
||||
*/
|
||||
if ((Index) var->varno != info->ht_rel->relid)
|
||||
continue;
|
||||
|
||||
|
@ -1040,3 +1040,27 @@ EXECUTE param_prep (1);
|
||||
|
||||
DEALLOCATE param_prep;
|
||||
RESET plan_cache_mode;
|
||||
-- test hypertable being non-toplevel equivalence member #6925
|
||||
CREATE TABLE i6925_t1(observed timestamptz not null, queryid int8, total_exec_time int8);
|
||||
CREATE TABLE i6925_t2(LIKE i6925_t1);
|
||||
SELECT table_name FROM create_hypertable('i6925_t1', 'observed');
|
||||
table_name
|
||||
i6925_t1
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE i6925_t1 SET (timescaledb.compress, timescaledb.compress_segmentby = 'queryid');
|
||||
NOTICE: default order by for hypertable "i6925_t1" is set to "observed DESC"
|
||||
INSERT INTO i6925_t1 SELECT '2020-01-01', 1, 1;
|
||||
SELECT count(compress_chunk(chunk_name)) FROM show_chunks('i6925_t1') chunk_name;
|
||||
count
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT queryid, lag(total_exec_time) OVER (PARTITION BY queryid) FROM (SELECT * FROM i6925_t1 UNION ALL SELECT * FROM i6925_t2) q;
|
||||
queryid | lag
|
||||
---------+-----
|
||||
1 |
|
||||
(1 row)
|
||||
|
||||
DROP TABLE i6925_t1;
|
||||
DROP TABLE i6925_t2;
|
||||
|
@ -1042,3 +1042,27 @@ EXECUTE param_prep (1);
|
||||
|
||||
DEALLOCATE param_prep;
|
||||
RESET plan_cache_mode;
|
||||
-- test hypertable being non-toplevel equivalence member #6925
|
||||
CREATE TABLE i6925_t1(observed timestamptz not null, queryid int8, total_exec_time int8);
|
||||
CREATE TABLE i6925_t2(LIKE i6925_t1);
|
||||
SELECT table_name FROM create_hypertable('i6925_t1', 'observed');
|
||||
table_name
|
||||
i6925_t1
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE i6925_t1 SET (timescaledb.compress, timescaledb.compress_segmentby = 'queryid');
|
||||
NOTICE: default order by for hypertable "i6925_t1" is set to "observed DESC"
|
||||
INSERT INTO i6925_t1 SELECT '2020-01-01', 1, 1;
|
||||
SELECT count(compress_chunk(chunk_name)) FROM show_chunks('i6925_t1') chunk_name;
|
||||
count
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT queryid, lag(total_exec_time) OVER (PARTITION BY queryid) FROM (SELECT * FROM i6925_t1 UNION ALL SELECT * FROM i6925_t2) q;
|
||||
queryid | lag
|
||||
---------+-----
|
||||
1 |
|
||||
(1 row)
|
||||
|
||||
DROP TABLE i6925_t1;
|
||||
DROP TABLE i6925_t2;
|
||||
|
@ -1042,3 +1042,27 @@ EXECUTE param_prep (1);
|
||||
|
||||
DEALLOCATE param_prep;
|
||||
RESET plan_cache_mode;
|
||||
-- test hypertable being non-toplevel equivalence member #6925
|
||||
CREATE TABLE i6925_t1(observed timestamptz not null, queryid int8, total_exec_time int8);
|
||||
CREATE TABLE i6925_t2(LIKE i6925_t1);
|
||||
SELECT table_name FROM create_hypertable('i6925_t1', 'observed');
|
||||
table_name
|
||||
i6925_t1
|
||||
(1 row)
|
||||
|
||||
ALTER TABLE i6925_t1 SET (timescaledb.compress, timescaledb.compress_segmentby = 'queryid');
|
||||
NOTICE: default order by for hypertable "i6925_t1" is set to "observed DESC"
|
||||
INSERT INTO i6925_t1 SELECT '2020-01-01', 1, 1;
|
||||
SELECT count(compress_chunk(chunk_name)) FROM show_chunks('i6925_t1') chunk_name;
|
||||
count
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT queryid, lag(total_exec_time) OVER (PARTITION BY queryid) FROM (SELECT * FROM i6925_t1 UNION ALL SELECT * FROM i6925_t2) q;
|
||||
queryid | lag
|
||||
---------+-----
|
||||
1 |
|
||||
(1 row)
|
||||
|
||||
DROP TABLE i6925_t1;
|
||||
DROP TABLE i6925_t2;
|
||||
|
@ -331,3 +331,18 @@ EXECUTE param_prep (2);
|
||||
EXECUTE param_prep (1);
|
||||
DEALLOCATE param_prep;
|
||||
RESET plan_cache_mode;
|
||||
|
||||
-- test hypertable being non-toplevel equivalence member #6925
|
||||
CREATE TABLE i6925_t1(observed timestamptz not null, queryid int8, total_exec_time int8);
|
||||
CREATE TABLE i6925_t2(LIKE i6925_t1);
|
||||
|
||||
SELECT table_name FROM create_hypertable('i6925_t1', 'observed');
|
||||
ALTER TABLE i6925_t1 SET (timescaledb.compress, timescaledb.compress_segmentby = 'queryid');
|
||||
INSERT INTO i6925_t1 SELECT '2020-01-01', 1, 1;
|
||||
SELECT count(compress_chunk(chunk_name)) FROM show_chunks('i6925_t1') chunk_name;
|
||||
|
||||
SELECT queryid, lag(total_exec_time) OVER (PARTITION BY queryid) FROM (SELECT * FROM i6925_t1 UNION ALL SELECT * FROM i6925_t2) q;
|
||||
|
||||
DROP TABLE i6925_t1;
|
||||
DROP TABLE i6925_t2;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user