mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-28 01:30:29 +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
|
* already refers a compressed column, it is a bug. See
|
||||||
* build_sortinfo().
|
* build_sortinfo().
|
||||||
*/
|
*/
|
||||||
Assert(compressed_em != NULL);
|
Ensure(compressed_em, "corresponding equivalence member not found");
|
||||||
|
|
||||||
required_compressed_pathkeys = lappend(required_compressed_pathkeys, pk);
|
required_compressed_pathkeys = lappend(required_compressed_pathkeys, pk);
|
||||||
|
|
||||||
@ -1482,17 +1482,6 @@ add_segmentby_to_equivalence_class(PlannerInfo *root, EquivalenceClass *cur_ec,
|
|||||||
Var *var;
|
Var *var;
|
||||||
Assert(!bms_overlap(cur_em->em_relids, info->compressed_rel->relids));
|
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
|
/* only consider EquivalenceMembers that are Vars, possibly with RelabelType, of the
|
||||||
* uncompressed chunk */
|
* uncompressed chunk */
|
||||||
var = (Var *) cur_em->em_expr;
|
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)))
|
if (!(var && IsA(var, Var)))
|
||||||
continue;
|
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)
|
if ((Index) var->varno != info->ht_rel->relid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1040,3 +1040,27 @@ EXECUTE param_prep (1);
|
|||||||
|
|
||||||
DEALLOCATE param_prep;
|
DEALLOCATE param_prep;
|
||||||
RESET plan_cache_mode;
|
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;
|
DEALLOCATE param_prep;
|
||||||
RESET plan_cache_mode;
|
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;
|
DEALLOCATE param_prep;
|
||||||
RESET plan_cache_mode;
|
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);
|
EXECUTE param_prep (1);
|
||||||
DEALLOCATE param_prep;
|
DEALLOCATE param_prep;
|
||||||
RESET plan_cache_mode;
|
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