Make SELECT DISTINCT handle non-var targetlists

The current SELECT DISTINCT pushdown code assumed that the targetlist
will always contain references to column attributes of the target
table.

So, even a simple "SELECT DISTINCT 1 from table;" causes a segmentation
fault because the "varno" field is not assigned. Fix this oversight.

Issue reported by @svenklemm

Fixes timescale/timescaledb-private#920
This commit is contained in:
Nikhil 2021-04-22 10:38:46 +05:30 committed by Nikhils
parent fc3f8305e3
commit a3d8f9fecd
3 changed files with 40 additions and 1 deletions

View File

@ -860,7 +860,7 @@ deparseDistinctClause(StringInfo buf, deparse_expr_cxt *context)
PlannerInfo *root = context->root;
Query *query = root->parse;
ListCell *l, *dc_l;
bool first = true;
bool first = true, varno_assigned = false;
Index varno;
RangeTblEntry *dc_rte;
RangeTblEntry *rte;
@ -889,6 +889,7 @@ deparseDistinctClause(StringInfo buf, deparse_expr_cxt *context)
{
varno = var->varno;
first = false;
varno_assigned = true;
}
if (varno != var->varno)
@ -899,6 +900,10 @@ deparseDistinctClause(StringInfo buf, deparse_expr_cxt *context)
return;
}
/* If there are no varno entries in the distinctClause, we are done */
if (!varno_assigned)
return;
/*
* If all distinctClause entries point to our rte->relid then it's
* safe to push down to the datanode

View File

@ -888,6 +888,34 @@ LIMIT 10;
Remote SQL: SELECT "time" FROM public.metrics_dist WHERE _timescaledb_internal.chunks_in(public.metrics_dist.*, ARRAY[1, 2, 3]) ORDER BY public.time_bucket('01:00:00'::interval, "time") ASC NULLS LAST
(23 rows)
SELECT DISTINCT without any var references is handled correctly
EXPLAIN (verbose, costs off)
SELECT DISTINCT 1, 'constx'
FROM metrics_dist;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------
Unique
Output: 1, 'constx'::text
-> Custom Scan (AsyncAppend)
Output: 1, 'constx'::text
-> Append
-> Custom Scan (DataNodeScan) on public.metrics_dist metrics_dist_1
Output: 1, 'constx'::text
Data node: data_node_1
Chunks: _dist_hyper_7_37_chunk, _dist_hyper_7_40_chunk, _dist_hyper_7_43_chunk
Remote SQL: SELECT NULL FROM public.metrics_dist WHERE _timescaledb_internal.chunks_in(public.metrics_dist.*, ARRAY[1, 2, 3])
-> Custom Scan (DataNodeScan) on public.metrics_dist metrics_dist_2
Output: 1, 'constx'::text
Data node: data_node_2
Chunks: _dist_hyper_7_38_chunk, _dist_hyper_7_41_chunk, _dist_hyper_7_44_chunk
Remote SQL: SELECT NULL FROM public.metrics_dist WHERE _timescaledb_internal.chunks_in(public.metrics_dist.*, ARRAY[1, 2, 3])
-> Custom Scan (DataNodeScan) on public.metrics_dist metrics_dist_3
Output: 1, 'constx'::text
Data node: data_node_3
Chunks: _dist_hyper_7_39_chunk, _dist_hyper_7_42_chunk, _dist_hyper_7_45_chunk
Remote SQL: SELECT NULL FROM public.metrics_dist WHERE _timescaledb_internal.chunks_in(public.metrics_dist.*, ARRAY[1, 2, 3])
(20 rows)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% RUNNING TESTS on table: metrics
%%% PREFIX:

View File

@ -133,3 +133,9 @@ SELECT DISTINCT time_bucket('1h',time) col1
FROM :TABLE_NAME
ORDER BY col1
LIMIT 10;
-- SELECT DISTINCT without any var references is handled correctly
\qecho SELECT DISTINCT without any var references is handled correctly
:PREFIX
SELECT DISTINCT 1, 'constx'
FROM :TABLE_NAME;