Don't segfault on queries using GROUPING

GROUPING will always return 0 outside of GROUPING SETS, CUBE, or ROLLUP
Since we don't support those, it makes sense to reject GROUPING in queries
pull/3653/head
Philip Dubé 2020-03-25 13:52:57 +00:00
parent 0ad1956551
commit 917cb6ae93
5 changed files with 49 additions and 4 deletions

View File

@ -225,13 +225,12 @@ HasNonPartitionColumnDistinctAgg(List *targetEntryList, Node *havingQual,
ListCell *varCell = NULL;
bool isPartitionColumn = false;
if (IsA(targetNode, Var))
if (!IsA(targetNode, Aggref))
{
continue;
}
Assert(IsA(targetNode, Aggref));
Aggref *targetAgg = (Aggref *) targetNode;
Aggref *targetAgg = castNode(Aggref, targetNode);
if (targetAgg->aggdistinct == NIL)
{
continue;

View File

@ -82,6 +82,7 @@ static bool IsReadIntermediateResultFunction(Node *node);
static bool IsReadIntermediateResultArrayFunction(Node *node);
static bool IsCitusExtraDataContainerFunc(Node *node);
static bool IsFunctionWithOid(Node *node, Oid funcOid);
static bool IsGroupingFunc(Node *node);
static bool ExtractFromExpressionWalker(Node *node,
QualifierWalkerContext *walkerContext);
static List * MultiTableNodeList(List *tableEntryList, List *rangeTableList);
@ -884,6 +885,16 @@ IsFunctionWithOid(Node *node, Oid funcOid)
}
/*
* IsGroupingFunc returns whether node is a GroupingFunc.
*/
static bool
IsGroupingFunc(Node *node)
{
return IsA(node, GroupingFunc);
}
/*
* FindIntermediateResultIdIfExists extracts the id of the intermediate result
* if the given RTE contains a read_intermediate_results function, NULL otherwise
@ -978,6 +989,13 @@ DeferErrorIfQueryNotSupported(Query *queryTree)
errorHint = filterHint;
}
if (FindNodeCheck((Node *) queryTree, IsGroupingFunc))
{
preconditionsSatisfied = false;
errorMessage = "could not run distributed query with GROUPING";
errorHint = filterHint;
}
bool hasTablesample = HasTablesample(queryTree);
if (hasTablesample)
{

View File

@ -1017,7 +1017,7 @@ AddAnyValueAggregates(Node *node, void *context)
}
}
}
if (IsA(node, Aggref))
if (IsA(node, Aggref) || IsA(node, GroupingFunc))
{
return node;
}

View File

@ -432,6 +432,21 @@ select key, count(distinct aggdata)
from aggdata group by key order by 1, 2;
ERROR: type "aggregate_support.aggdata" does not exist
CONTEXT: while executing command on localhost:xxxxx
-- GROUPING parses to GroupingFunc, distinct from Aggref
-- These three queries represent edge cases implementation would have to consider
-- For now we error out of all three
select grouping(id)
from aggdata group by id order by 1 limit 3;
ERROR: could not run distributed query with GROUPING
HINT: Consider using an equality filter on the distributed table's partition column.
select key, grouping(val)
from aggdata group by key, val order by 1, 2;
ERROR: could not run distributed query with GROUPING
HINT: Consider using an equality filter on the distributed table's partition column.
select key, grouping(val), sum(distinct valf)
from aggdata group by key, val order by 1, 2;
ERROR: could not run distributed query with GROUPING
HINT: Consider using an equality filter on the distributed table's partition column.
-- Test https://github.com/citusdata/citus/issues/3328
create table nulltable(id int);
insert into nulltable values (0);

View File

@ -204,6 +204,19 @@ RESET citus.task_executor_type;
select key, count(distinct aggdata)
from aggdata group by key order by 1, 2;
-- GROUPING parses to GroupingFunc, distinct from Aggref
-- These three queries represent edge cases implementation would have to consider
-- For now we error out of all three
select grouping(id)
from aggdata group by id order by 1 limit 3;
select key, grouping(val)
from aggdata group by key, val order by 1, 2;
select key, grouping(val), sum(distinct valf)
from aggdata group by key, val order by 1, 2;
-- Test https://github.com/citusdata/citus/issues/3328
create table nulltable(id int);
insert into nulltable values (0);