mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
pgindent file.
This commit is contained in:
parent
2ee522954d
commit
692a65e6ff
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.33 1999/01/25 18:02:18 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.34 1999/01/26 05:57:14 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -926,115 +926,109 @@ del_agg_clause(Node *clause)
|
|||||||
* GROUP BY sid
|
* GROUP BY sid
|
||||||
* HAVING MIN(pid) > 1; (pid is used but never selected for!!!).
|
* HAVING MIN(pid) > 1; (pid is used but never selected for!!!).
|
||||||
* To be able to handle queries like that correctly we have to extend the actual targetlist
|
* To be able to handle queries like that correctly we have to extend the actual targetlist
|
||||||
* (which will be the one used for the GROUP node later on) by these attributes. */
|
* (which will be the one used for the GROUP node later on) by these attributes. */
|
||||||
List *
|
List *
|
||||||
check_having_qual_for_vars(Node *clause, List *targetlist_so_far)
|
check_having_qual_for_vars(Node *clause, List *targetlist_so_far)
|
||||||
{
|
{
|
||||||
List *t;
|
List *t;
|
||||||
|
|
||||||
|
|
||||||
if (IsA(clause, Var))
|
if (IsA(clause, Var))
|
||||||
{
|
|
||||||
RelOptInfo tmp_rel;
|
|
||||||
|
|
||||||
|
|
||||||
tmp_rel.targetlist = targetlist_so_far;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ha! A Var node!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Check if the VAR is already contained in the targetlist */
|
|
||||||
if (tlist_member((Var *)clause, (List *)targetlist_so_far) == NULL)
|
|
||||||
{
|
{
|
||||||
add_tl_element(&tmp_rel, (Var *)clause);
|
RelOptInfo tmp_rel;
|
||||||
|
|
||||||
|
|
||||||
|
tmp_rel.targetlist = targetlist_so_far;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ha! A Var node!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Check if the VAR is already contained in the targetlist */
|
||||||
|
if (tlist_member((Var *) clause, (List *) targetlist_so_far) == NULL)
|
||||||
|
add_tl_element(&tmp_rel, (Var *) clause);
|
||||||
|
|
||||||
|
return tmp_rel.targetlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmp_rel.targetlist;
|
else if (is_funcclause(clause) || not_clause(clause) ||
|
||||||
}
|
or_clause(clause) || and_clause(clause))
|
||||||
|
|
||||||
else if (is_funcclause(clause) || not_clause(clause) ||
|
|
||||||
or_clause(clause) || and_clause(clause))
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is a function. Recursively call this routine for its
|
|
||||||
* arguments...
|
|
||||||
*/
|
|
||||||
foreach(t, ((Expr *) clause)->args)
|
|
||||||
{
|
{
|
||||||
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
|
||||||
}
|
|
||||||
return targetlist_so_far;
|
|
||||||
}
|
|
||||||
else if (IsA(clause, Aggref))
|
|
||||||
{
|
|
||||||
targetlist_so_far =
|
|
||||||
check_having_qual_for_vars(((Aggref *) clause)->target, targetlist_so_far);
|
|
||||||
return targetlist_so_far;
|
|
||||||
}
|
|
||||||
else if (IsA(clause, ArrayRef))
|
|
||||||
{
|
|
||||||
ArrayRef *aref = (ArrayRef *) clause;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an arrayref. Recursively call this routine for its
|
* This is a function. Recursively call this routine for its
|
||||||
* expression and its index expression...
|
* arguments...
|
||||||
*/
|
*/
|
||||||
foreach(t, aref->refupperindexpr)
|
foreach(t, ((Expr *) clause)->args)
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
||||||
|
return targetlist_so_far;
|
||||||
|
}
|
||||||
|
else if (IsA(clause, Aggref))
|
||||||
{
|
{
|
||||||
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
targetlist_so_far =
|
||||||
|
check_having_qual_for_vars(((Aggref *) clause)->target, targetlist_so_far);
|
||||||
|
return targetlist_so_far;
|
||||||
}
|
}
|
||||||
foreach(t, aref->reflowerindexpr)
|
else if (IsA(clause, ArrayRef))
|
||||||
{
|
{
|
||||||
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
ArrayRef *aref = (ArrayRef *) clause;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an arrayref. Recursively call this routine for its
|
||||||
|
* expression and its index expression...
|
||||||
|
*/
|
||||||
|
foreach(t, aref->refupperindexpr)
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
||||||
|
foreach(t, aref->reflowerindexpr)
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(aref->refexpr, targetlist_so_far);
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(aref->refassgnexpr, targetlist_so_far);
|
||||||
|
|
||||||
|
return targetlist_so_far;
|
||||||
}
|
}
|
||||||
targetlist_so_far = check_having_qual_for_vars(aref->refexpr, targetlist_so_far);
|
else if (is_opclause(clause))
|
||||||
targetlist_so_far = check_having_qual_for_vars(aref->refassgnexpr, targetlist_so_far);
|
|
||||||
|
|
||||||
return targetlist_so_far;
|
|
||||||
}
|
|
||||||
else if (is_opclause(clause))
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an operator. Recursively call this routine for both its
|
|
||||||
* left and right operands
|
|
||||||
*/
|
|
||||||
Node *left = (Node *) get_leftop((Expr *) clause);
|
|
||||||
Node *right = (Node *) get_rightop((Expr *) clause);
|
|
||||||
|
|
||||||
if (left != (Node *) NULL)
|
|
||||||
targetlist_so_far = check_having_qual_for_vars(left, targetlist_so_far);
|
|
||||||
if (right != (Node *) NULL)
|
|
||||||
targetlist_so_far = check_having_qual_for_vars(right, targetlist_so_far);
|
|
||||||
|
|
||||||
return targetlist_so_far;
|
|
||||||
}
|
|
||||||
else if (IsA(clause, Param) || IsA(clause, Const))
|
|
||||||
{
|
|
||||||
/* do nothing! */
|
|
||||||
return targetlist_so_far;
|
|
||||||
}
|
|
||||||
/* If we get to a sublink, then we only have to check the lefthand side of the expression
|
|
||||||
* to see if there are any additional VARs */
|
|
||||||
else if (IsA(clause, SubLink))
|
|
||||||
{
|
|
||||||
foreach(t,((List *)((SubLink *)clause)->lefthand))
|
|
||||||
{
|
{
|
||||||
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
|
||||||
|
/*
|
||||||
|
* This is an operator. Recursively call this routine for both its
|
||||||
|
* left and right operands
|
||||||
|
*/
|
||||||
|
Node *left = (Node *) get_leftop((Expr *) clause);
|
||||||
|
Node *right = (Node *) get_rightop((Expr *) clause);
|
||||||
|
|
||||||
|
if (left != (Node *) NULL)
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(left, targetlist_so_far);
|
||||||
|
if (right != (Node *) NULL)
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(right, targetlist_so_far);
|
||||||
|
|
||||||
|
return targetlist_so_far;
|
||||||
|
}
|
||||||
|
else if (IsA(clause, Param) ||IsA(clause, Const))
|
||||||
|
{
|
||||||
|
/* do nothing! */
|
||||||
|
return targetlist_so_far;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we get to a sublink, then we only have to check the lefthand
|
||||||
|
* side of the expression to see if there are any additional VARs
|
||||||
|
*/
|
||||||
|
else if (IsA(clause, SubLink))
|
||||||
|
{
|
||||||
|
foreach(t, ((List *) ((SubLink *) clause)->lefthand))
|
||||||
|
targetlist_so_far = check_having_qual_for_vars(lfirst(t), targetlist_so_far);
|
||||||
|
return targetlist_so_far;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ooops! we can not handle that!
|
||||||
|
*/
|
||||||
|
elog(ERROR, "check_having_qual_for_vars: Can not handle this having_qual! %d\n",
|
||||||
|
nodeTag(clause));
|
||||||
|
return NIL;
|
||||||
}
|
}
|
||||||
return targetlist_so_far;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Ooops! we can not handle that!
|
|
||||||
*/
|
|
||||||
elog(ERROR, "check_having_qual_for_vars: Can not handle this having_qual! %d\n",
|
|
||||||
nodeTag(clause));
|
|
||||||
return NIL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check_having_qual_for_aggs takes the havingQual, the targetlist and the groupClause
|
/* check_having_qual_for_aggs takes the havingQual, the targetlist and the groupClause
|
||||||
@ -1044,35 +1038,37 @@ check_having_qual_for_vars(Node *clause, List *targetlist_so_far)
|
|||||||
List *
|
List *
|
||||||
check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupClause)
|
check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupClause)
|
||||||
{
|
{
|
||||||
List *t, *l1;
|
List *t,
|
||||||
|
*l1;
|
||||||
List *agg_list = NIL;
|
List *agg_list = NIL;
|
||||||
|
|
||||||
int contained_in_group_clause = 0;
|
int contained_in_group_clause = 0;
|
||||||
|
|
||||||
|
|
||||||
if (IsA(clause, Var))
|
if (IsA(clause, Var))
|
||||||
{
|
{
|
||||||
TargetEntry *subplanVar;
|
TargetEntry *subplanVar;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ha! A Var node!
|
* Ha! A Var node!
|
||||||
*/
|
*/
|
||||||
subplanVar = match_varid((Var *) clause, subplanTargetList);
|
subplanVar = match_varid((Var *) clause, subplanTargetList);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the varno & varattno fields of the var node to point to the resdom->resno
|
* Change the varno & varattno fields of the var node to point to
|
||||||
* fields of the subplan (lefttree)
|
* the resdom->resno fields of the subplan (lefttree)
|
||||||
*/
|
*/
|
||||||
((Var *) clause)->varattno = subplanVar->resdom->resno;
|
((Var *) clause)->varattno = subplanVar->resdom->resno;
|
||||||
|
|
||||||
return NIL;
|
return NIL;
|
||||||
|
|
||||||
}
|
}
|
||||||
/***S*H***/
|
/***S*H***/
|
||||||
else if (is_funcclause(clause) || not_clause(clause) ||
|
else if (is_funcclause(clause) || not_clause(clause) ||
|
||||||
or_clause(clause) || and_clause(clause))
|
or_clause(clause) || and_clause(clause))
|
||||||
{
|
{
|
||||||
int new_length=0, old_length=0;
|
int new_length = 0,
|
||||||
|
old_length = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a function. Recursively call this routine for its
|
* This is a function. Recursively call this routine for its
|
||||||
@ -1080,31 +1076,35 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupCla
|
|||||||
*/
|
*/
|
||||||
foreach(t, ((Expr *) clause)->args)
|
foreach(t, ((Expr *) clause)->args)
|
||||||
{
|
{
|
||||||
old_length=length((List *)agg_list);
|
old_length = length((List *) agg_list);
|
||||||
|
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
|
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
|
|
||||||
/* The arguments of OR or AND clauses are comparisons or relations
|
/*
|
||||||
* and because we are in the havingQual there must be at least one operand
|
* The arguments of OR or AND clauses are comparisons or
|
||||||
* using an aggregate function. If so, we will find it and the length of the
|
* relations and because we are in the havingQual there must
|
||||||
* agg_list will be increased after the above call to
|
* be at least one operand using an aggregate function. If so,
|
||||||
* check_having_qual_for_aggs. If there are no aggregates used, the query
|
* we will find it and the length of the agg_list will be
|
||||||
* could have been formulated using the 'where' clause */
|
* increased after the above call to
|
||||||
if(((new_length=length((List *)agg_list)) == old_length) || (new_length == 0))
|
* check_having_qual_for_aggs. If there are no aggregates
|
||||||
{
|
* used, the query could have been formulated using the
|
||||||
elog(ERROR,"This could have been done in a where clause!!");
|
* 'where' clause
|
||||||
return NIL;
|
*/
|
||||||
}
|
if (((new_length = length((List *) agg_list)) == old_length) || (new_length == 0))
|
||||||
|
{
|
||||||
|
elog(ERROR, "This could have been done in a where clause!!");
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return agg_list;
|
return agg_list;
|
||||||
}
|
}
|
||||||
else if (IsA(clause, Aggref))
|
else if (IsA(clause, Aggref))
|
||||||
{
|
{
|
||||||
return lcons(clause,
|
return lcons(clause,
|
||||||
check_having_qual_for_aggs(((Aggref *) clause)->target, subplanTargetList,
|
check_having_qual_for_aggs(((Aggref *) clause)->target, subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
}
|
}
|
||||||
else if (IsA(clause, ArrayRef))
|
else if (IsA(clause, ArrayRef))
|
||||||
{
|
{
|
||||||
@ -1117,21 +1117,21 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupCla
|
|||||||
foreach(t, aref->refupperindexpr)
|
foreach(t, aref->refupperindexpr)
|
||||||
{
|
{
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
|
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
}
|
}
|
||||||
foreach(t, aref->reflowerindexpr)
|
foreach(t, aref->reflowerindexpr)
|
||||||
{
|
{
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
|
check_having_qual_for_aggs(lfirst(t), subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
}
|
}
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(aref->refexpr, subplanTargetList,
|
check_having_qual_for_aggs(aref->refexpr, subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(aref->refassgnexpr, subplanTargetList,
|
check_having_qual_for_aggs(aref->refassgnexpr, subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
|
|
||||||
return agg_list;
|
return agg_list;
|
||||||
}
|
}
|
||||||
@ -1147,92 +1147,102 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupCla
|
|||||||
|
|
||||||
if (left != (Node *) NULL)
|
if (left != (Node *) NULL)
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(left, subplanTargetList,
|
check_having_qual_for_aggs(left, subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
if (right != (Node *) NULL)
|
if (right != (Node *) NULL)
|
||||||
agg_list = nconc(agg_list,
|
agg_list = nconc(agg_list,
|
||||||
check_having_qual_for_aggs(right, subplanTargetList,
|
check_having_qual_for_aggs(right, subplanTargetList,
|
||||||
groupClause));
|
groupClause));
|
||||||
|
|
||||||
return agg_list;
|
return agg_list;
|
||||||
}
|
}
|
||||||
else if (IsA(clause, Param) || IsA(clause, Const))
|
else if (IsA(clause, Param) ||IsA(clause, Const))
|
||||||
{
|
{
|
||||||
/* do nothing! */
|
/* do nothing! */
|
||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
/* This is for Sublinks which show up as EXPR nodes. All the other EXPR nodes
|
|
||||||
* (funcclauses, and_clauses, or_clauses) were caught above */
|
/*
|
||||||
|
* This is for Sublinks which show up as EXPR nodes. All the other
|
||||||
|
* EXPR nodes (funcclauses, and_clauses, or_clauses) were caught above
|
||||||
|
*/
|
||||||
else if (IsA(clause, Expr))
|
else if (IsA(clause, Expr))
|
||||||
{
|
{
|
||||||
/* Only the lefthand side of the sublink has to be checked for aggregates
|
|
||||||
* to be attached to result_plan->aggs (see planner.c:union_planner() )
|
|
||||||
*/
|
|
||||||
foreach(t,((List *)((SubLink *)((SubPlan *)
|
|
||||||
((Expr *)clause)->oper)->sublink)->lefthand))
|
|
||||||
{
|
|
||||||
agg_list =
|
|
||||||
nconc(agg_list,
|
|
||||||
check_having_qual_for_aggs(lfirst(t),
|
|
||||||
subplanTargetList, groupClause));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The first argument of ...->oper has also to be checked */
|
/*
|
||||||
{
|
* Only the lefthand side of the sublink has to be checked for
|
||||||
List *tmp_ptr;
|
* aggregates to be attached to result_plan->aggs (see
|
||||||
|
* planner.c:union_planner() )
|
||||||
foreach(tmp_ptr, ((SubLink *)((SubPlan *)
|
*/
|
||||||
((Expr *)clause)->oper)->sublink)->oper)
|
foreach(t, ((List *) ((SubLink *) ((SubPlan *)
|
||||||
|
((Expr *) clause)->oper)->sublink)->lefthand))
|
||||||
{
|
{
|
||||||
agg_list =
|
agg_list =
|
||||||
nconc(agg_list,
|
nconc(agg_list,
|
||||||
check_having_qual_for_aggs((Node *)lfirst(((Expr *)
|
check_having_qual_for_aggs(lfirst(t),
|
||||||
lfirst(tmp_ptr))->args),
|
subplanTargetList, groupClause));
|
||||||
subplanTargetList, groupClause));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* All arguments to the Sublink node are attributes from outside used within
|
/* The first argument of ...->oper has also to be checked */
|
||||||
* the sublink. Here we have to check that only attributes that is grouped for
|
{
|
||||||
* are used! */
|
List *tmp_ptr;
|
||||||
foreach(t,((Expr *)clause)->args)
|
|
||||||
{
|
|
||||||
contained_in_group_clause = 0;
|
|
||||||
|
|
||||||
foreach(l1,groupClause)
|
foreach(tmp_ptr, ((SubLink *) ((SubPlan *)
|
||||||
{
|
((Expr *) clause)->oper)->sublink)->oper)
|
||||||
if (tlist_member(lfirst(t),lcons(((GroupClause *)lfirst(l1))->entry,NIL)) !=
|
{
|
||||||
NULL)
|
agg_list =
|
||||||
{
|
nconc(agg_list,
|
||||||
contained_in_group_clause=1;
|
check_having_qual_for_aggs((Node *) lfirst(((Expr *)
|
||||||
}
|
lfirst(tmp_ptr))->args),
|
||||||
}
|
subplanTargetList, groupClause));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If the use of the attribute is allowed (i.e. it is in the groupClause)
|
/*
|
||||||
* we have to adjust the varnos and varattnos */
|
* All arguments to the Sublink node are attributes from outside
|
||||||
if (contained_in_group_clause)
|
* used within the sublink. Here we have to check that only
|
||||||
{
|
* attributes that is grouped for are used!
|
||||||
agg_list =
|
*/
|
||||||
nconc(agg_list,
|
foreach(t, ((Expr *) clause)->args)
|
||||||
check_having_qual_for_aggs(lfirst(t),
|
{
|
||||||
subplanTargetList, groupClause));
|
contained_in_group_clause = 0;
|
||||||
}
|
|
||||||
else
|
foreach(l1, groupClause)
|
||||||
{
|
{
|
||||||
elog(ERROR,"You must group by the attribute used from outside!");
|
if (tlist_member(lfirst(t), lcons(((GroupClause *) lfirst(l1))->entry, NIL)) !=
|
||||||
return NIL;
|
NULL)
|
||||||
}
|
contained_in_group_clause = 1;
|
||||||
}
|
}
|
||||||
return agg_list;
|
|
||||||
}
|
/*
|
||||||
|
* If the use of the attribute is allowed (i.e. it is in the
|
||||||
|
* groupClause) we have to adjust the varnos and varattnos
|
||||||
|
*/
|
||||||
|
if (contained_in_group_clause)
|
||||||
|
{
|
||||||
|
agg_list =
|
||||||
|
nconc(agg_list,
|
||||||
|
check_having_qual_for_aggs(lfirst(t),
|
||||||
|
subplanTargetList, groupClause));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elog(ERROR, "You must group by the attribute used from outside!");
|
||||||
|
return NIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return agg_list;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Ooops! we can not handle that!
|
/*
|
||||||
*/
|
* Ooops! we can not handle that!
|
||||||
elog(ERROR, "check_having_qual_for_aggs: Can not handle this having_qual! %d\n",
|
*/
|
||||||
nodeTag(clause));
|
elog(ERROR, "check_having_qual_for_aggs: Can not handle this having_qual! %d\n",
|
||||||
return NIL;
|
nodeTag(clause));
|
||||||
}
|
return NIL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/***S*H***/ /* End */
|
|
||||||
|
/***S*H***//* End */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user