aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/view.c5
-rw-r--r--src/backend/executor/nodeAgg.c25
-rw-r--r--src/backend/executor/nodeMergejoin.c6
-rw-r--r--src/backend/optimizer/plan/planner.c177
-rw-r--r--src/backend/optimizer/plan/setrefs.c255
-rw-r--r--src/backend/optimizer/plan/subselect.c7
-rw-r--r--src/backend/parser/analyze.c26
-rw-r--r--src/backend/parser/gram.c835
-rw-r--r--src/backend/parser/gram.y5
-rw-r--r--src/backend/rewrite/rewriteHandler.c36
-rw-r--r--src/backend/rewrite/rewriteManip.c149
-rw-r--r--src/include/optimizer/planmain.h6
-rw-r--r--src/include/rewrite/rewriteManip.h4
13 files changed, 998 insertions, 538 deletions
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index 6360f004b75..ac4a4d0d204 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.22 1998/06/15 19:28:17 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.23 1998/07/19 05:49:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -222,6 +222,9 @@ UpdateRangeTableOfViewParse(char *viewName, Query *viewParse)
OffsetVarNodes((Node *) viewParse->targetList, 2);
OffsetVarNodes(viewParse->qual, 2);
+ OffsetVarNodes(viewParse->havingQual, 2);
+
+
/*
* find the old range table...
*/
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 58c837e8e9c..28f50bdd4f4 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -109,22 +109,24 @@ ExecAgg(Agg *node)
bool isNull = FALSE,
isNull1 = FALSE,
isNull2 = FALSE;
-
-
- do {
-
+ bool qual_result;
+
/* ---------------------
* get state info from node
* ---------------------
*/
+ /* We loop retrieving groups until we find one matching node->plan.qual */
+ do {
+
aggstate = node->aggstate;
if (aggstate->agg_done)
return NULL;
estate = node->plan.state;
econtext = aggstate->csstate.cstate.cs_ExprContext;
+
nagg = length(node->aggs);
aggregates = (Aggreg **) palloc(sizeof(Aggreg *) * nagg);
@@ -235,8 +237,7 @@ ExecAgg(Agg *node)
}
}
}
-
-
+
/* ----------------
* for each tuple from the the outer plan, apply all the aggregates
* ----------------
@@ -474,11 +475,6 @@ ExecAgg(Agg *node)
* slot and return it.
* ----------------
*/
-
- }
- while((ExecQual(fix_opids(node->plan.qual),econtext)!=true) &&
- (node->plan.qual!=NULL));
-
ExecStoreTuple(oneTuple,
aggstate->csstate.css_ScanTupleSlot,
@@ -488,8 +484,13 @@ ExecAgg(Agg *node)
resultSlot = ExecProject(projInfo, &isDone);
+ /* As long as the retrieved group does not match the qualifications it is ignored and
+ * the next group is fetched */
+ qual_result=ExecQual(fix_opids(node->plan.qual),econtext);
if (oneTuple)
- pfree(oneTuple);
+ pfree(oneTuple);
+ }
+ while((node->plan.qual!=NULL) && (qual_result!=true));
return resultSlot;
}
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index d3a1bdb62ea..5483c864d35 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.16 1998/06/15 19:28:22 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.17 1998/07/19 05:49:13 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -365,7 +365,9 @@ CleanUpSort(Plan *plan)
{
Sort *sort = (Sort *) plan;
- psort_end(sort);
+ /* This may need to be fixed or moved somewhere else, bjm */
+ /* psort_end(sort); */
+
}
}
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index c88d201501c..51a93517c17 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.27 1998/04/15 15:29:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.28 1998/07/19 05:49:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -95,6 +95,11 @@ Plan *
union_planner(Query *parse)
{
List *tlist = parse->targetList;
+
+ /* copy the original tlist, we will need the original one
+ * for the AGG node later on */
+ List *new_tlist = new_unsorted_tlist(tlist);
+
List *rangetable = parse->rtable;
Plan *result_plan = (Plan *) NULL;
@@ -104,12 +109,12 @@ union_planner(Query *parse)
if (parse->unionClause)
{
- result_plan = (Plan *) plan_union_queries(parse);
- /* XXX do we need to do this? bjm 12/19/97 */
- tlist = preprocess_targetlist(tlist,
- parse->commandType,
- parse->resultRelation,
- parse->rtable);
+ result_plan = (Plan *) plan_union_queries(parse);
+ /* XXX do we need to do this? bjm 12/19/97 */
+ tlist = preprocess_targetlist(tlist,
+ parse->commandType,
+ parse->resultRelation,
+ parse->rtable);
}
else if ((rt_index =
first_inherit_rt_entry(rangetable)) != -1)
@@ -117,33 +122,64 @@ union_planner(Query *parse)
result_plan = (Plan *) plan_inherit_queries(parse, rt_index);
/* XXX do we need to do this? bjm 12/19/97 */
tlist = preprocess_targetlist(tlist,
- parse->commandType,
- parse->resultRelation,
- parse->rtable);
+ parse->commandType,
+ parse->resultRelation,
+ parse->rtable);
}
else
{
- List **vpm = NULL;
-
- tlist = preprocess_targetlist(tlist,
- parse->commandType,
- parse->resultRelation,
- parse->rtable);
- if (parse->rtable != NULL)
+ List **vpm = NULL;
+
+ /* This is only necessary if aggregates are in use in queries like:
+ * SELECT sid
+ * FROM part
+ * GROUP BY sid
+ * HAVING MIN(pid) > 1; (pid is used but never selected for!!!)
+ * because the function 'query_planner' creates the plan for the lefttree
+ * of the 'GROUP' node and returns only those attributes contained in 'tlist'.
+ * The original 'tlist' contains only 'sid' here and that's why we have to
+ * to extend it to attributes which are not selected but are used in the
+ * havingQual. */
+
+ /* 'check_having_qual_for_vars' takes the havingQual and the actual 'tlist'
+ * as arguments and recursively scans the havingQual for attributes
+ * (VAR nodes) that are not contained in 'tlist' yet. If so, it creates
+ * a new entry and attaches it to the list 'new_tlist' (consisting of the
+ * VAR node and the RESDOM node as usual with tlists :-) ) */
+ if (parse->hasAggs)
+ {
+ if (parse->havingQual != NULL)
{
- vpm = (List **) palloc(length(parse->rtable) * sizeof(List *));
- memset(vpm, 0, length(parse->rtable) * sizeof(List *));
+ new_tlist = check_having_qual_for_vars(parse->havingQual,new_tlist);
}
- PlannerVarParam = lcons(vpm, PlannerVarParam);
- result_plan = query_planner(parse,
- parse->commandType,
- tlist,
- (List *) parse->qual);
- PlannerVarParam = lnext(PlannerVarParam);
- if (vpm != NULL)
- pfree(vpm);
+ }
+
+ new_tlist = preprocess_targetlist(new_tlist,
+ parse->commandType,
+ parse->resultRelation,
+ parse->rtable);
+
+ /* Here starts the original (pre having) code */
+ tlist = preprocess_targetlist(tlist,
+ parse->commandType,
+ parse->resultRelation,
+ parse->rtable);
+
+ if (parse->rtable != NULL)
+ {
+ vpm = (List **) palloc(length(parse->rtable) * sizeof(List *));
+ memset(vpm, 0, length(parse->rtable) * sizeof(List *));
+ }
+ PlannerVarParam = lcons(vpm, PlannerVarParam);
+ result_plan = query_planner(parse,
+ parse->commandType,
+ new_tlist,
+ (List *) parse->qual);
+ PlannerVarParam = lnext(PlannerVarParam);
+ if (vpm != NULL)
+ pfree(vpm);
}
-
+
/*
* If we have a GROUP BY clause, insert a group node (with the
* appropriate sort node.)
@@ -160,12 +196,12 @@ union_planner(Query *parse)
*/
tuplePerGroup = parse->hasAggs;
+ /* Use 'new_tlist' instead of 'tlist' */
result_plan =
- make_groupPlan(&tlist,
+ make_groupPlan(&new_tlist,
tuplePerGroup,
parse->groupClause,
result_plan);
-
}
/*
@@ -173,6 +209,11 @@ union_planner(Query *parse)
*/
if (parse->hasAggs)
{
+ int old_length=0, new_length=0;
+
+ /* Create the AGG node but use 'tlist' not 'new_tlist' as target list because we
+ * don't want the additional attributes (only used for the havingQual, see above)
+ * to show up in the result */
result_plan = (Plan *) make_agg(tlist, result_plan);
/*
@@ -180,23 +221,71 @@ union_planner(Query *parse)
* the result tuple of the subplans.
*/
((Agg *) result_plan)->aggs =
- set_agg_tlist_references((Agg *) result_plan);
+ set_agg_tlist_references((Agg *) result_plan);
- if(parse->havingQual != NULL) {
- List *clause;
- /* set qpqual of having clause */
- ((Agg *) result_plan)->plan.qual=cnfify((Expr *)parse->havingQual,true);
-
- foreach(clause, ((Agg *) result_plan)->plan.qual)
- {
- ((Agg *) result_plan)->aggs = nconc(((Agg *) result_plan)->aggs,
- check_having_qual_for_aggs((Node *) lfirst(clause),
- ((Agg *) result_plan)->plan.lefttree->targetlist));
- }
- }
- }
+ if(parse->havingQual!=NULL)
+ {
+ List *clause;
+ List **vpm = NULL;
+
+
+ /* stuff copied from above to handle the use of attributes from outside
+ * in subselects */
+ if (parse->rtable != NULL)
+ {
+ vpm = (List **) palloc(length(parse->rtable) * sizeof(List *));
+ memset(vpm, 0, length(parse->rtable) * sizeof(List *));
+ }
+ PlannerVarParam = lcons(vpm, PlannerVarParam);
+
+ /* There is a subselect in the havingQual, so we have to process it
+ * using the same function as for a subselect in 'where' */
+ if (parse->hasSubLinks)
+ {
+ (List *) parse->havingQual =
+ (List *) SS_process_sublinks((Node *) parse->havingQual);
+ }
+
+ /* convert the havingQual to conjunctive normal form (cnf) */
+ (List *) parse->havingQual=cnfify((Expr *)(Node *) parse->havingQual,true);
+
+ /* Calculate the opfids from the opnos (=select the correct functions for
+ * the used VAR datatypes) */
+ (List *) parse->havingQual=fix_opids((List *) parse->havingQual);
+
+ ((Agg *) result_plan)->plan.qual=(List *) parse->havingQual;
+
+ /* Check every clause of the havingQual for aggregates used and append
+ * them to result_plan->aggs */
+ foreach(clause, ((Agg *) result_plan)->plan.qual)
+ {
+ /* Make sure there are aggregates in the havingQual
+ * if so, the list must be longer after check_having_qual_for_aggs */
+ old_length=length(((Agg *) result_plan)->aggs);
+
+ ((Agg *) result_plan)->aggs = nconc(((Agg *) result_plan)->aggs,
+ check_having_qual_for_aggs((Node *) lfirst(clause),
+ ((Agg *) result_plan)->plan.lefttree->targetlist,
+ ((List *) parse->groupClause)));
+
+ /* Have a look at the length of the returned list. If there is no
+ * difference, no aggregates have been found and that means, that
+ * the Qual belongs to the where clause */
+ if (((new_length=length(((Agg *) result_plan)->aggs)) == old_length) ||
+ (new_length == 0))
+ {
+ elog(ERROR,"This could have been done in a where clause!!");
+ return (Plan *)NIL;
+ }
+ }
+ PlannerVarParam = lnext(PlannerVarParam);
+ if (vpm != NULL)
+ pfree(vpm);
+ }
+ }
+
/*
* For now, before we hand back the plan, check to see if there is a
* user-specified sort that needs to be done. Eventually, this will
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index c1e3194133b..96b203498ff 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.22 1998/06/15 19:28:44 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.23 1998/07/19 05:49:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -898,12 +898,139 @@ del_agg_clause(Node *clause)
}
+/* check_having_qual_for_vars takes the the havingQual and the actual targetlist as arguments
+ * and recursively scans the havingQual for attributes that are not included in the targetlist
+ * yet. Attributes contained in the havingQual but not in the targetlist show up with queries
+ * like:
+ * SELECT sid
+ * FROM part
+ * GROUP BY sid
+ * 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
+ * (which will be the one used for the GROUP node later on) by these attributes. */
List *
-check_having_qual_for_aggs(Node *clause, List *subplanTargetList)
+check_having_qual_for_vars(Node *clause, List *targetlist_so_far)
{
- List *t;
+ List *t;
+
+
+ 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);
+ }
+
+ return tmp_rel.targetlist;
+ }
+
+ 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, Aggreg))
+ {
+ targetlist_so_far =
+ check_having_qual_for_vars(((Aggreg *) 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
+ * 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;
+ }
+ 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);
+ }
+ 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
+ * as arguments and scans the havingQual recursively for aggregates. If an aggregate is
+ * found it is attached to a list and returned by the function. (All the returned lists
+ * are concenated to result_plan->aggs in planner.c:union_planner() */
+List *
+check_having_qual_for_aggs(Node *clause, List *subplanTargetList, List *groupClause)
+{
+ List *t, *l1;
List *agg_list = NIL;
+ int contained_in_group_clause = 0;
+
+
if (IsA(clause, Var))
{
TargetEntry *subplanVar;
@@ -914,32 +1041,50 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList)
subplanVar = match_varid((Var *) clause, subplanTargetList);
/*
- * Change the varno & varattno fields of the var node.
- *
- */
+ * Change the varno & varattno fields of the var node to point to the resdom->resno
+ * fields of the subplan (lefttree)
+ */
((Var *) clause)->varattno = subplanVar->resdom->resno;
+
return NIL;
+
}
else if (is_funcclause(clause) || not_clause(clause) ||
or_clause(clause) || and_clause(clause))
{
-
+ int new_length=0, old_length=0;
+
/*
* This is a function. Recursively call this routine for its
- * arguments...
+ * arguments... (i.e. for AND, OR, ... clauses!)
*/
foreach(t, ((Expr *) clause)->args)
{
- agg_list = nconc(agg_list,
- check_having_qual_for_aggs(lfirst(t), subplanTargetList));
+ old_length=length((List *)agg_list);
+
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(lfirst(t), subplanTargetList,
+ 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
+ * using an aggregate function. If so, we will find it and the lenght of the
+ * agg_list will be increased after the above call to
+ * check_having_qual_for_aggs. If there are no aggregates used, the query
+ * could have been formulated using the 'where' clause */
+ 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;
}
else if (IsA(clause, Aggreg))
{
return lcons(clause,
- check_having_qual_for_aggs(((Aggreg *) clause)->target, subplanTargetList));
-
+ check_having_qual_for_aggs(((Aggreg *) clause)->target, subplanTargetList,
+ groupClause));
}
else if (IsA(clause, ArrayRef))
{
@@ -952,17 +1097,21 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList)
foreach(t, aref->refupperindexpr)
{
agg_list = nconc(agg_list,
- check_having_qual_for_aggs(lfirst(t), subplanTargetList));
+ check_having_qual_for_aggs(lfirst(t), subplanTargetList,
+ groupClause));
}
foreach(t, aref->reflowerindexpr)
{
agg_list = nconc(agg_list,
- check_having_qual_for_aggs(lfirst(t), subplanTargetList));
+ check_having_qual_for_aggs(lfirst(t), subplanTargetList,
+ groupClause));
}
agg_list = nconc(agg_list,
- check_having_qual_for_aggs(aref->refexpr, subplanTargetList));
+ check_having_qual_for_aggs(aref->refexpr, subplanTargetList,
+ groupClause));
agg_list = nconc(agg_list,
- check_having_qual_for_aggs(aref->refassgnexpr, subplanTargetList));
+ check_having_qual_for_aggs(aref->refassgnexpr, subplanTargetList,
+ groupClause));
return agg_list;
}
@@ -978,27 +1127,79 @@ check_having_qual_for_aggs(Node *clause, List *subplanTargetList)
if (left != (Node *) NULL)
agg_list = nconc(agg_list,
- check_having_qual_for_aggs(left, subplanTargetList));
+ check_having_qual_for_aggs(left, subplanTargetList,
+ groupClause));
if (right != (Node *) NULL)
agg_list = nconc(agg_list,
- check_having_qual_for_aggs(right, subplanTargetList));
+ check_having_qual_for_aggs(right, subplanTargetList,
+ groupClause));
return agg_list;
}
- else if (IsA(clause, Param) ||IsA(clause, Const))
+ else if (IsA(clause, Param) || IsA(clause, Const))
{
/* do nothing! */
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 */
+ 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));
+ }
+
+
+ /* All arguments to the Sublink node are attributes from outside used within
+ * the sublink. Here we have to check that only attributes that is grouped for
+ * are used! */
+ foreach(t,((Expr *)clause)->args)
+ {
+ contained_in_group_clause = 0;
+
+ foreach(l1,groupClause)
+ {
+ if (tlist_member(lfirst(t),lcons(((GroupClause *)lfirst(l1))->entry,NIL)) !=
+ NULL)
+ {
+ contained_in_group_clause=1;
+ }
+ }
+
+ /* 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
- {
-
- /*
- * Ooops! we can not handle that!
- */
- elog(ERROR, "check_having_qual_for_aggs: Can not handle this having_qual!\n");
- return NIL;
- }
+ {
+ /*
+ * Ooops! we can not handle that!
+ */
+ elog(ERROR, "check_having_qual_for_aggs: Can not handle this having_qual! %d\n",
+ nodeTag(clause));
+ return NIL;
+ }
}
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 72d023dccf5..040c6732ccc 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -404,8 +404,13 @@ SS_process_sublinks(Node *expr)
((Expr *) expr)->args = (List *)
SS_process_sublinks((Node *) ((Expr *) expr)->args);
else if (IsA(expr, SubLink))/* got it! */
- expr = _make_subplan((SubLink *) expr);
+ {
+ lfirst(((Expr *) lfirst(((SubLink *)expr)->oper))->args) =
+ lfirst(((SubLink *)expr)->lefthand);
+ expr = _make_subplan((SubLink *) expr);
+ }
+
return (expr);
}
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 95e19e8cb59..4865d2de6da 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.76 1998/05/29 13:39:30 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.77 1998/07/19 05:49:17 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -327,6 +327,9 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
/* fix where clause */
qry->qual = transformWhereClause(pstate, stmt->whereClause);
+ /* The havingQual has a similar meaning as "qual" in the where statement.
+ * So we can easily use the code from the "where clause" with some additional
+ * traversals done in .../optimizer/plan/planner.c */
qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
qry->hasSubLinks = pstate->p_hasSubLinks;
@@ -356,6 +359,15 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
qry->unionall = stmt->unionall;
qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
+ /* If there is a havingQual but there are no aggregates, then there is something wrong
+ * with the query because having must contain aggregates in its expressions!
+ * Otherwise the query could have been formulated using the where clause. */
+ if((qry->hasAggs == false) && (qry->havingQual != NULL))
+ {
+ elog(ERROR,"This is not a valid having query!");
+ return (Query *)NIL;
+ }
+
return (Query *) qry;
}
@@ -795,6 +807,9 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
qry->qual = transformWhereClause(pstate, stmt->whereClause);
+ /* The havingQual has a similar meaning as "qual" in the where statement.
+ * So we can easily use the code from the "where clause" with some additional
+ * traversals done in .../optimizer/plan/planner.c */
qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
qry->hasSubLinks = pstate->p_hasSubLinks;
@@ -820,6 +835,15 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
qry->unionall = stmt->unionall;
qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
+ /* If there is a havingQual but there are no aggregates, then there is something wrong
+ * with the query because having must contain aggregates in its expressions!
+ * Otherwise the query could have been formulated using the where clause. */
+ if((qry->hasAggs == false) && (qry->havingQual != NULL))
+ {
+ elog(ERROR,"This is not a valid having query!");
+ return (Query *)NIL;
+ }
+
return (Query *) qry;
}
diff --git a/src/backend/parser/gram.c b/src/backend/parser/gram.c
index fa1e1cef6cb..670e052257f 100644
--- a/src/backend/parser/gram.c
+++ b/src/backend/parser/gram.c
@@ -218,7 +218,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.16 1998/07/15 22:16:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.17 1998/07/19 05:49:18 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -795,45 +795,45 @@ static const short yyrline[] = { 0,
2434, 2440, 2444, 2462, 2463, 2466, 2467, 2470, 2471, 2474,
2475, 2476, 2477, 2480, 2481, 2484, 2485, 2488, 2496, 2504,
2514, 2515, 2516, 2517, 2518, 2519, 2529, 2530, 2533, 2535,
- 2537, 2541, 2542, 2545, 2546, 2549, 2557, 2565, 2575, 2582,
- 2594, 2599, 2600, 2603, 2605, 2607, 2611, 2617, 2623, 2631,
- 2632, 2634, 2636, 2638, 2640, 2642, 2644, 2648, 2649, 2652,
- 2653, 2654, 2657, 2658, 2661, 2669, 2677, 2687, 2688, 2691,
- 2698, 2706, 2708, 2710, 2714, 2716, 2718, 2733, 2755, 2756,
- 2763, 2764, 2765, 2768, 2776, 2777, 2786, 2792, 2797, 2803,
- 2811, 2813, 2815, 2817, 2821, 2832, 2838, 2845, 2850, 2856,
- 2864, 2870, 2883, 2910, 2929, 2949, 2950, 2951, 2952, 2955,
- 2956, 2959, 2960, 2963, 2964, 2967, 2973, 2980, 2986, 2994,
- 2995, 2996, 2997, 2998, 2999, 3002, 3003, 3006, 3007, 3008,
- 3009, 3010, 3011, 3012, 3013, 3014, 3024, 3026, 3043, 3053,
- 3063, 3076, 3089, 3095, 3101, 3105, 3111, 3112, 3113, 3114,
- 3115, 3116, 3117, 3118, 3121, 3122, 3133, 3138, 3140, 3142,
- 3150, 3152, 3154, 3156, 3158, 3160, 3162, 3164, 3166, 3168,
- 3170, 3172, 3188, 3204, 3206, 3208, 3210, 3212, 3214, 3216,
- 3228, 3235, 3242, 3257, 3272, 3294, 3309, 3331, 3338, 3345,
- 3355, 3362, 3369, 3377, 3384, 3391, 3398, 3405, 3407, 3409,
- 3411, 3418, 3428, 3438, 3448, 3458, 3464, 3470, 3470, 3484,
- 3484, 3498, 3508, 3518, 3528, 3538, 3548, 3558, 3568, 3578,
- 3588, 3598, 3608, 3618, 3628, 3638, 3648, 3658, 3668, 3678,
- 3688, 3698, 3708, 3718, 3728, 3738, 3740, 3742, 3752, 3757,
- 3759, 3767, 3769, 3771, 3773, 3775, 3777, 3779, 3781, 3783,
- 3799, 3815, 3817, 3819, 3821, 3823, 3830, 3837, 3852, 3867,
- 3889, 3904, 3926, 3933, 3940, 3947, 3955, 3962, 3969, 3976,
- 3985, 3992, 3999, 4003, 4005, 4007, 4011, 4018, 4022, 4023,
- 4024, 4027, 4029, 4033, 4038, 4040, 4042, 4044, 4046, 4048,
- 4050, 4052, 4068, 4084, 4086, 4088, 4090, 4092, 4100, 4107,
- 4114, 4121, 4129, 4136, 4143, 4150, 4159, 4163, 4167, 4169,
- 4178, 4180, 4184, 4186, 4188, 4192, 4198, 4202, 4204, 4210,
- 4216, 4220, 4222, 4228, 4236, 4246, 4248, 4250, 4261, 4263,
- 4265, 4280, 4287, 4294, 4313, 4315, 4320, 4327, 4334, 4346,
- 4360, 4361, 4364, 4369, 4381, 4382, 4383, 4384, 4385, 4391,
- 4392, 4394, 4395, 4400, 4407, 4414, 4421, 4429, 4431, 4441,
- 4453, 4460, 4461, 4462, 4469, 4471, 4473, 4484, 4485, 4486,
- 4487, 4488, 4489, 4490, 4491, 4492, 4493, 4494, 4495, 4496,
- 4497, 4498, 4499, 4500, 4501, 4502, 4503, 4504, 4505, 4506,
- 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516,
- 4517, 4530, 4531, 4532, 4533, 4534, 4535, 4536, 4537, 4538,
- 4539, 4540, 4541, 4542, 4543, 4544, 4547, 4554
+ 2537, 2541, 2542, 2545, 2546, 2549, 2557, 2565, 2575, 2579,
+ 2591, 2596, 2597, 2600, 2602, 2604, 2608, 2614, 2620, 2628,
+ 2629, 2631, 2633, 2635, 2637, 2639, 2641, 2645, 2646, 2649,
+ 2650, 2651, 2654, 2655, 2658, 2666, 2674, 2684, 2685, 2688,
+ 2695, 2703, 2705, 2707, 2711, 2713, 2715, 2730, 2752, 2753,
+ 2760, 2761, 2762, 2765, 2773, 2774, 2783, 2789, 2794, 2800,
+ 2808, 2810, 2812, 2814, 2818, 2829, 2835, 2842, 2847, 2853,
+ 2861, 2867, 2880, 2907, 2926, 2946, 2947, 2948, 2949, 2952,
+ 2953, 2956, 2957, 2960, 2961, 2964, 2970, 2977, 2983, 2991,
+ 2992, 2993, 2994, 2995, 2996, 2999, 3000, 3003, 3004, 3005,
+ 3006, 3007, 3008, 3009, 3010, 3011, 3021, 3023, 3040, 3050,
+ 3060, 3073, 3086, 3092, 3098, 3102, 3108, 3109, 3110, 3111,
+ 3112, 3113, 3114, 3115, 3118, 3119, 3130, 3135, 3137, 3139,
+ 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165,
+ 3167, 3169, 3185, 3201, 3203, 3205, 3207, 3209, 3211, 3213,
+ 3225, 3232, 3239, 3254, 3269, 3291, 3306, 3328, 3335, 3342,
+ 3352, 3359, 3366, 3374, 3381, 3388, 3395, 3402, 3404, 3406,
+ 3408, 3415, 3425, 3435, 3445, 3455, 3461, 3467, 3467, 3481,
+ 3481, 3495, 3505, 3515, 3525, 3535, 3545, 3555, 3565, 3575,
+ 3585, 3595, 3605, 3615, 3625, 3635, 3645, 3655, 3665, 3675,
+ 3685, 3695, 3705, 3715, 3725, 3735, 3737, 3739, 3749, 3754,
+ 3756, 3764, 3766, 3768, 3770, 3772, 3774, 3776, 3778, 3780,
+ 3796, 3812, 3814, 3816, 3818, 3820, 3827, 3834, 3849, 3864,
+ 3886, 3901, 3923, 3930, 3937, 3944, 3952, 3959, 3966, 3973,
+ 3982, 3989, 3996, 4000, 4002, 4004, 4008, 4015, 4019, 4020,
+ 4021, 4024, 4026, 4030, 4035, 4037, 4039, 4041, 4043, 4045,
+ 4047, 4049, 4065, 4081, 4083, 4085, 4087, 4089, 4097, 4104,
+ 4111, 4118, 4126, 4133, 4140, 4147, 4156, 4160, 4164, 4166,
+ 4175, 4177, 4181, 4183, 4185, 4189, 4195, 4199, 4201, 4207,
+ 4213, 4217, 4219, 4225, 4233, 4243, 4245, 4247, 4258, 4260,
+ 4262, 4277, 4284, 4291, 4310, 4312, 4317, 4324, 4331, 4343,
+ 4357, 4358, 4361, 4366, 4378, 4379, 4380, 4381, 4382, 4388,
+ 4389, 4391, 4392, 4397, 4404, 4411, 4418, 4426, 4428, 4438,
+ 4450, 4457, 4458, 4459, 4466, 4468, 4470, 4481, 4482, 4483,
+ 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493,
+ 4494, 4495, 4496, 4497, 4498, 4499, 4500, 4501, 4502, 4503,
+ 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513,
+ 4514, 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, 4535,
+ 4536, 4537, 4538, 4539, 4540, 4541, 4544, 4551
};
#endif
@@ -6907,45 +6907,42 @@ case 468:
case 469:
#line 2576 "gram.y"
{
-#if FALSE
- elog(ERROR,"HAVING clause not yet implemented");
-#endif
yyval.node = yyvsp[0].node;
;
break;}
case 470:
-#line 2582 "gram.y"
+#line 2579 "gram.y"
{ yyval.node = NULL; ;
break;}
case 471:
-#line 2595 "gram.y"
+#line 2592 "gram.y"
{
yyval.list = NIL;
elog(ERROR,"JOIN not yet implemented");
;
break;}
case 472:
-#line 2599 "gram.y"
+#line 2596 "gram.y"
{ yyval.list = yyvsp[0].list; ;
break;}
case 473:
-#line 2600 "gram.y"
+#line 2597 "gram.y"
{ yyval.list = NIL; ;
break;}
case 474:
-#line 2604 "gram.y"
+#line 2601 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, yyvsp[0].range); ;
break;}
case 475:
-#line 2606 "gram.y"
+#line 2603 "gram.y"
{ elog(ERROR,"CROSS JOIN not yet implemented"); ;
break;}
case 476:
-#line 2608 "gram.y"
+#line 2605 "gram.y"
{ yyval.list = lcons(yyvsp[0].range, NIL); ;
break;}
case 477:
-#line 2612 "gram.y"
+#line 2609 "gram.y"
{
yyval.range = makeNode(RangeVar);
yyval.range->relExpr = yyvsp[-2].relexp;
@@ -6953,7 +6950,7 @@ case 477:
;
break;}
case 478:
-#line 2618 "gram.y"
+#line 2615 "gram.y"
{
yyval.range = makeNode(RangeVar);
yyval.range->relExpr = yyvsp[-1].relexp;
@@ -6961,7 +6958,7 @@ case 478:
;
break;}
case 479:
-#line 2624 "gram.y"
+#line 2621 "gram.y"
{
yyval.range = makeNode(RangeVar);
yyval.range->relExpr = yyvsp[0].relexp;
@@ -6969,67 +6966,67 @@ case 479:
;
break;}
case 480:
-#line 2631 "gram.y"
+#line 2628 "gram.y"
{ yyval.str = NULL; ;
break;}
case 481:
-#line 2633 "gram.y"
+#line 2630 "gram.y"
{ elog(ERROR,"FULL OUTER JOIN not yet implemented"); ;
break;}
case 482:
-#line 2635 "gram.y"
+#line 2632 "gram.y"
{ elog(ERROR,"LEFT OUTER JOIN not yet implemented"); ;
break;}
case 483:
-#line 2637 "gram.y"
+#line 2634 "gram.y"
{ elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); ;
break;}
case 484:
-#line 2639 "gram.y"
+#line 2636 "gram.y"
{ elog(ERROR,"OUTER JOIN not yet implemented"); ;
break;}
case 485:
-#line 2641 "gram.y"
+#line 2638 "gram.y"
{ elog(ERROR,"INNER JOIN not yet implemented"); ;
break;}
case 486:
-#line 2643 "gram.y"
+#line 2640 "gram.y"
{ elog(ERROR,"UNION JOIN not yet implemented"); ;
break;}
case 487:
-#line 2645 "gram.y"
+#line 2642 "gram.y"
{ elog(ERROR,"INNER JOIN not yet implemented"); ;
break;}
case 488:
-#line 2648 "gram.y"
+#line 2645 "gram.y"
{ yyval.str = NULL; ;
break;}
case 489:
-#line 2649 "gram.y"
+#line 2646 "gram.y"
{ yyval.str = NULL; /* no qualifiers */ ;
break;}
case 490:
-#line 2652 "gram.y"
+#line 2649 "gram.y"
{ yyval.str = NULL; ;
break;}
case 491:
-#line 2653 "gram.y"
+#line 2650 "gram.y"
{ yyval.str = NULL; ;
break;}
case 492:
-#line 2654 "gram.y"
+#line 2651 "gram.y"
{ yyval.str = NULL; /* no qualifiers */ ;
break;}
case 493:
-#line 2657 "gram.y"
+#line 2654 "gram.y"
{ yyval.list = lcons(yyvsp[0].sortgroupby, NIL); ;
break;}
case 494:
-#line 2658 "gram.y"
+#line 2655 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, yyvsp[0].sortgroupby); ;
break;}
case 495:
-#line 2662 "gram.y"
+#line 2659 "gram.y"
{
yyval.sortgroupby = makeNode(SortGroupBy);
yyval.sortgroupby->resno = 0;
@@ -7039,7 +7036,7 @@ case 495:
;
break;}
case 496:
-#line 2670 "gram.y"
+#line 2667 "gram.y"
{
yyval.sortgroupby = makeNode(SortGroupBy);
yyval.sortgroupby->resno = 0;
@@ -7049,7 +7046,7 @@ case 496:
;
break;}
case 497:
-#line 2678 "gram.y"
+#line 2675 "gram.y"
{
yyval.sortgroupby = makeNode(SortGroupBy);
yyval.sortgroupby->resno = yyvsp[0].ival;
@@ -7059,15 +7056,15 @@ case 497:
;
break;}
case 498:
-#line 2687 "gram.y"
+#line 2684 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 499:
-#line 2688 "gram.y"
+#line 2685 "gram.y"
{ yyval.node = NULL; /* no qualifiers */ ;
break;}
case 500:
-#line 2692 "gram.y"
+#line 2689 "gram.y"
{
/* normal relations */
yyval.relexp = makeNode(RelExpr);
@@ -7076,7 +7073,7 @@ case 500:
;
break;}
case 501:
-#line 2699 "gram.y"
+#line 2696 "gram.y"
{
/* inheritance query */
yyval.relexp = makeNode(RelExpr);
@@ -7085,31 +7082,31 @@ case 501:
;
break;}
case 502:
-#line 2707 "gram.y"
+#line 2704 "gram.y"
{ yyval.list = lcons(makeInteger(-1), yyvsp[0].list); ;
break;}
case 503:
-#line 2709 "gram.y"
+#line 2706 "gram.y"
{ yyval.list = lcons(makeInteger(yyvsp[-2].ival), yyvsp[0].list); ;
break;}
case 504:
-#line 2711 "gram.y"
+#line 2708 "gram.y"
{ yyval.list = NIL; ;
break;}
case 505:
-#line 2715 "gram.y"
+#line 2712 "gram.y"
{ yyval.list = lcons(makeInteger(-1), yyvsp[0].list); ;
break;}
case 506:
-#line 2717 "gram.y"
+#line 2714 "gram.y"
{ yyval.list = lcons(makeInteger(yyvsp[-2].ival), yyvsp[0].list); ;
break;}
case 507:
-#line 2719 "gram.y"
+#line 2716 "gram.y"
{ yyval.list = NIL; ;
break;}
case 508:
-#line 2734 "gram.y"
+#line 2731 "gram.y"
{
yyval.typnam = yyvsp[-1].typnam;
yyval.typnam->arrayBounds = yyvsp[0].list;
@@ -7133,14 +7130,14 @@ case 508:
;
break;}
case 510:
-#line 2757 "gram.y"
+#line 2754 "gram.y"
{
yyval.typnam = yyvsp[0].typnam;
yyval.typnam->setof = TRUE;
;
break;}
case 514:
-#line 2769 "gram.y"
+#line 2766 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType(yyvsp[0].str);
@@ -7148,15 +7145,15 @@ case 514:
;
break;}
case 515:
-#line 2776 "gram.y"
+#line 2773 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 516:
-#line 2777 "gram.y"
+#line 2774 "gram.y"
{ yyval.str = xlateSqlType("type"); ;
break;}
case 517:
-#line 2787 "gram.y"
+#line 2784 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType(yyvsp[0].str);
@@ -7164,14 +7161,14 @@ case 517:
;
break;}
case 518:
-#line 2793 "gram.y"
+#line 2790 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType("float");
;
break;}
case 519:
-#line 2798 "gram.y"
+#line 2795 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType("integer");
@@ -7179,7 +7176,7 @@ case 519:
;
break;}
case 520:
-#line 2804 "gram.y"
+#line 2801 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType("integer");
@@ -7187,23 +7184,23 @@ case 520:
;
break;}
case 521:
-#line 2812 "gram.y"
+#line 2809 "gram.y"
{ yyval.str = xlateSqlType("float8"); ;
break;}
case 522:
-#line 2814 "gram.y"
+#line 2811 "gram.y"
{ yyval.str = xlateSqlType("float8"); ;
break;}
case 523:
-#line 2816 "gram.y"
+#line 2813 "gram.y"
{ yyval.str = xlateSqlType("decimal"); ;
break;}
case 524:
-#line 2818 "gram.y"
+#line 2815 "gram.y"
{ yyval.str = xlateSqlType("numeric"); ;
break;}
case 525:
-#line 2822 "gram.y"
+#line 2819 "gram.y"
{
if (yyvsp[-1].ival < 1)
elog(ERROR,"precision for FLOAT must be at least 1");
@@ -7216,13 +7213,13 @@ case 525:
;
break;}
case 526:
-#line 2833 "gram.y"
+#line 2830 "gram.y"
{
yyval.str = xlateSqlType("float8");
;
break;}
case 527:
-#line 2839 "gram.y"
+#line 2836 "gram.y"
{
if (yyvsp[-3].ival != 9)
elog(ERROR,"NUMERIC precision %d must be 9",yyvsp[-3].ival);
@@ -7231,20 +7228,20 @@ case 527:
;
break;}
case 528:
-#line 2846 "gram.y"
+#line 2843 "gram.y"
{
if (yyvsp[-1].ival != 9)
elog(ERROR,"NUMERIC precision %d must be 9",yyvsp[-1].ival);
;
break;}
case 529:
-#line 2851 "gram.y"
+#line 2848 "gram.y"
{
yyval.str = NULL;
;
break;}
case 530:
-#line 2857 "gram.y"
+#line 2854 "gram.y"
{
if (yyvsp[-3].ival > 9)
elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",yyvsp[-3].ival);
@@ -7254,7 +7251,7 @@ case 530:
;
break;}
case 531:
-#line 2865 "gram.y"
+#line 2862 "gram.y"
{
if (yyvsp[-1].ival > 9)
elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",yyvsp[-1].ival);
@@ -7262,13 +7259,13 @@ case 531:
;
break;}
case 532:
-#line 2871 "gram.y"
+#line 2868 "gram.y"
{
yyval.str = NULL;
;
break;}
case 533:
-#line 2884 "gram.y"
+#line 2881 "gram.y"
{
yyval.typnam = makeNode(TypeName);
if (strcasecmp(yyvsp[-3].str, "char") == 0)
@@ -7297,7 +7294,7 @@ case 533:
;
break;}
case 534:
-#line 2911 "gram.y"
+#line 2908 "gram.y"
{
yyval.typnam = makeNode(TypeName);
/* Let's try to make all single-character types into bpchar(1)
@@ -7316,7 +7313,7 @@ case 534:
;
break;}
case 535:
-#line 2930 "gram.y"
+#line 2927 "gram.y"
{
char *type, *c;
if ((yyvsp[-1].str == NULL) || (strcasecmp(yyvsp[-1].str, "sql_text") == 0)) {
@@ -7338,47 +7335,47 @@ case 535:
;
break;}
case 536:
-#line 2949 "gram.y"
+#line 2946 "gram.y"
{ yyval.str = xlateSqlType(yyvsp[0].boolean? "varchar": "char"); ;
break;}
case 537:
-#line 2950 "gram.y"
+#line 2947 "gram.y"
{ yyval.str = xlateSqlType("varchar"); ;
break;}
case 538:
-#line 2951 "gram.y"
+#line 2948 "gram.y"
{ yyval.str = xlateSqlType(yyvsp[0].boolean? "varchar": "char"); ;
break;}
case 539:
-#line 2952 "gram.y"
+#line 2949 "gram.y"
{ yyval.str = xlateSqlType(yyvsp[0].boolean? "varchar": "char"); ;
break;}
case 540:
-#line 2955 "gram.y"
+#line 2952 "gram.y"
{ yyval.boolean = TRUE; ;
break;}
case 541:
-#line 2956 "gram.y"
+#line 2953 "gram.y"
{ yyval.boolean = FALSE; ;
break;}
case 542:
-#line 2959 "gram.y"
+#line 2956 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 543:
-#line 2960 "gram.y"
+#line 2957 "gram.y"
{ yyval.str = NULL; ;
break;}
case 544:
-#line 2963 "gram.y"
+#line 2960 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 545:
-#line 2964 "gram.y"
+#line 2961 "gram.y"
{ yyval.str = NULL; ;
break;}
case 546:
-#line 2968 "gram.y"
+#line 2965 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType(yyvsp[0].str);
@@ -7386,7 +7383,7 @@ case 546:
;
break;}
case 547:
-#line 2974 "gram.y"
+#line 2971 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType("timestamp");
@@ -7395,7 +7392,7 @@ case 547:
;
break;}
case 548:
-#line 2981 "gram.y"
+#line 2978 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType("time");
@@ -7403,7 +7400,7 @@ case 548:
;
break;}
case 549:
-#line 2987 "gram.y"
+#line 2984 "gram.y"
{
yyval.typnam = makeNode(TypeName);
yyval.typnam->name = xlateSqlType("interval");
@@ -7411,79 +7408,79 @@ case 549:
;
break;}
case 550:
-#line 2994 "gram.y"
+#line 2991 "gram.y"
{ yyval.str = "year"; ;
break;}
case 551:
-#line 2995 "gram.y"
+#line 2992 "gram.y"
{ yyval.str = "month"; ;
break;}
case 552:
-#line 2996 "gram.y"
+#line 2993 "gram.y"
{ yyval.str = "day"; ;
break;}
case 553:
-#line 2997 "gram.y"
+#line 2994 "gram.y"
{ yyval.str = "hour"; ;
break;}
case 554:
-#line 2998 "gram.y"
+#line 2995 "gram.y"
{ yyval.str = "minute"; ;
break;}
case 555:
-#line 2999 "gram.y"
+#line 2996 "gram.y"
{ yyval.str = "second"; ;
break;}
case 556:
-#line 3002 "gram.y"
+#line 2999 "gram.y"
{ yyval.boolean = TRUE; ;
break;}
case 557:
-#line 3003 "gram.y"
+#line 3000 "gram.y"
{ yyval.boolean = FALSE; ;
break;}
case 558:
-#line 3006 "gram.y"
+#line 3003 "gram.y"
{ yyval.list = lcons(yyvsp[0].str, NIL); ;
break;}
case 559:
-#line 3007 "gram.y"
+#line 3004 "gram.y"
{ yyval.list = NIL; ;
break;}
case 560:
-#line 3008 "gram.y"
+#line 3005 "gram.y"
{ yyval.list = NIL; ;
break;}
case 561:
-#line 3009 "gram.y"
+#line 3006 "gram.y"
{ yyval.list = NIL; ;
break;}
case 562:
-#line 3010 "gram.y"
+#line 3007 "gram.y"
{ yyval.list = NIL; ;
break;}
case 563:
-#line 3011 "gram.y"
+#line 3008 "gram.y"
{ yyval.list = NIL; ;
break;}
case 564:
-#line 3012 "gram.y"
+#line 3009 "gram.y"
{ yyval.list = NIL; ;
break;}
case 565:
-#line 3013 "gram.y"
+#line 3010 "gram.y"
{ yyval.list = NIL; ;
break;}
case 566:
-#line 3014 "gram.y"
+#line 3011 "gram.y"
{ yyval.list = NIL; ;
break;}
case 567:
-#line 3025 "gram.y"
+#line 3022 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 568:
-#line 3027 "gram.y"
+#line 3024 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
@@ -7491,7 +7488,7 @@ case 568:
;
break;}
case 569:
-#line 3044 "gram.y"
+#line 3041 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = yyvsp[-5].list;
@@ -7503,7 +7500,7 @@ case 569:
;
break;}
case 570:
-#line 3054 "gram.y"
+#line 3051 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = yyvsp[-6].list;
@@ -7515,7 +7512,7 @@ case 570:
;
break;}
case 571:
-#line 3064 "gram.y"
+#line 3061 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = yyvsp[-6].list;
@@ -7530,7 +7527,7 @@ case 571:
;
break;}
case 572:
-#line 3077 "gram.y"
+#line 3074 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = yyvsp[-5].list;
@@ -7545,86 +7542,86 @@ case 572:
;
break;}
case 573:
-#line 3090 "gram.y"
+#line 3087 "gram.y"
{
yyval.node = makeRowExpr(yyvsp[-3].str, yyvsp[-5].list, yyvsp[-1].list);
;
break;}
case 574:
-#line 3096 "gram.y"
+#line 3093 "gram.y"
{
yyval.list = lappend(yyvsp[-2].list, yyvsp[0].node);
;
break;}
case 575:
-#line 3102 "gram.y"
+#line 3099 "gram.y"
{
yyval.list = lappend(yyvsp[-2].list, yyvsp[0].node);
;
break;}
case 576:
-#line 3106 "gram.y"
+#line 3103 "gram.y"
{
yyval.list = lcons(yyvsp[0].node, NIL);
;
break;}
case 577:
-#line 3111 "gram.y"
+#line 3108 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 578:
-#line 3112 "gram.y"
+#line 3109 "gram.y"
{ yyval.str = "<"; ;
break;}
case 579:
-#line 3113 "gram.y"
+#line 3110 "gram.y"
{ yyval.str = "="; ;
break;}
case 580:
-#line 3114 "gram.y"
+#line 3111 "gram.y"
{ yyval.str = ">"; ;
break;}
case 581:
-#line 3115 "gram.y"
+#line 3112 "gram.y"
{ yyval.str = "+"; ;
break;}
case 582:
-#line 3116 "gram.y"
+#line 3113 "gram.y"
{ yyval.str = "-"; ;
break;}
case 583:
-#line 3117 "gram.y"
+#line 3114 "gram.y"
{ yyval.str = "*"; ;
break;}
case 584:
-#line 3118 "gram.y"
+#line 3115 "gram.y"
{ yyval.str = "/"; ;
break;}
case 585:
-#line 3121 "gram.y"
+#line 3118 "gram.y"
{ yyval.ival = ANY_SUBLINK; ;
break;}
case 586:
-#line 3122 "gram.y"
+#line 3119 "gram.y"
{ yyval.ival = ALL_SUBLINK; ;
break;}
case 587:
-#line 3134 "gram.y"
+#line 3131 "gram.y"
{
yyvsp[-1].attr->indirection = yyvsp[0].list;
yyval.node = (Node *)yyvsp[-1].attr;
;
break;}
case 588:
-#line 3139 "gram.y"
+#line 3136 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 589:
-#line 3141 "gram.y"
+#line 3138 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 590:
-#line 3143 "gram.y"
+#line 3140 "gram.y"
{
/* could be a column name or a relation_name */
Ident *n = makeNode(Ident);
@@ -7634,51 +7631,51 @@ case 590:
;
break;}
case 591:
-#line 3151 "gram.y"
+#line 3148 "gram.y"
{ yyval.node = makeA_Expr(OP, "-", NULL, yyvsp[0].node); ;
break;}
case 592:
-#line 3153 "gram.y"
+#line 3150 "gram.y"
{ yyval.node = makeA_Expr(OP, "+", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 593:
-#line 3155 "gram.y"
+#line 3152 "gram.y"
{ yyval.node = makeA_Expr(OP, "-", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 594:
-#line 3157 "gram.y"
+#line 3154 "gram.y"
{ yyval.node = makeA_Expr(OP, "/", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 595:
-#line 3159 "gram.y"
+#line 3156 "gram.y"
{ yyval.node = makeA_Expr(OP, "*", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 596:
-#line 3161 "gram.y"
+#line 3158 "gram.y"
{ yyval.node = makeA_Expr(OP, "<", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 597:
-#line 3163 "gram.y"
+#line 3160 "gram.y"
{ yyval.node = makeA_Expr(OP, ">", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 598:
-#line 3165 "gram.y"
+#line 3162 "gram.y"
{ yyval.node = makeA_Expr(OP, "=", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 599:
-#line 3167 "gram.y"
+#line 3164 "gram.y"
{ yyval.node = makeA_Expr(OP, ":", NULL, yyvsp[0].node); ;
break;}
case 600:
-#line 3169 "gram.y"
+#line 3166 "gram.y"
{ yyval.node = makeA_Expr(OP, ";", NULL, yyvsp[0].node); ;
break;}
case 601:
-#line 3171 "gram.y"
+#line 3168 "gram.y"
{ yyval.node = makeA_Expr(OP, "|", NULL, yyvsp[0].node); ;
break;}
case 602:
-#line 3173 "gram.y"
+#line 3170 "gram.y"
{
yyval.node = (Node *)yyvsp[-2].node;
/* AexprConst can be either A_Const or ParamNo */
@@ -7696,7 +7693,7 @@ case 602:
;
break;}
case 603:
-#line 3189 "gram.y"
+#line 3186 "gram.y"
{
yyval.node = (Node *)yyvsp[-3].node;
/* AexprConst can be either A_Const or ParamNo */
@@ -7714,31 +7711,31 @@ case 603:
;
break;}
case 604:
-#line 3205 "gram.y"
+#line 3202 "gram.y"
{ yyval.node = yyvsp[-1].node; ;
break;}
case 605:
-#line 3207 "gram.y"
+#line 3204 "gram.y"
{ yyval.node = makeIndexable(yyvsp[-1].str,yyvsp[-2].node,yyvsp[0].node); ;
break;}
case 606:
-#line 3209 "gram.y"
+#line 3206 "gram.y"
{ yyval.node = makeIndexable("~~", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 607:
-#line 3211 "gram.y"
+#line 3208 "gram.y"
{ yyval.node = makeA_Expr(OP, "!~~", yyvsp[-3].node, yyvsp[0].node); ;
break;}
case 608:
-#line 3213 "gram.y"
+#line 3210 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[-1].str, NULL, yyvsp[0].node); ;
break;}
case 609:
-#line 3215 "gram.y"
+#line 3212 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[0].str, yyvsp[-1].node, NULL); ;
break;}
case 610:
-#line 3217 "gram.y"
+#line 3214 "gram.y"
{
/* cheap hack for aggregate (eg. count) */
FuncCall *n = makeNode(FuncCall);
@@ -7752,7 +7749,7 @@ case 610:
;
break;}
case 611:
-#line 3229 "gram.y"
+#line 3226 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = yyvsp[-2].str;
@@ -7761,7 +7758,7 @@ case 611:
;
break;}
case 612:
-#line 3236 "gram.y"
+#line 3233 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = yyvsp[-3].str;
@@ -7770,7 +7767,7 @@ case 612:
;
break;}
case 613:
-#line 3243 "gram.y"
+#line 3240 "gram.y"
{
A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
@@ -7787,7 +7784,7 @@ case 613:
;
break;}
case 614:
-#line 3258 "gram.y"
+#line 3255 "gram.y"
{
A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
@@ -7804,7 +7801,7 @@ case 614:
;
break;}
case 615:
-#line 3273 "gram.y"
+#line 3270 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
A_Const *s = makeNode(A_Const);
@@ -7828,7 +7825,7 @@ case 615:
;
break;}
case 616:
-#line 3295 "gram.y"
+#line 3292 "gram.y"
{
A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
@@ -7845,7 +7842,7 @@ case 616:
;
break;}
case 617:
-#line 3310 "gram.y"
+#line 3307 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
A_Const *s = makeNode(A_Const);
@@ -7869,7 +7866,7 @@ case 617:
;
break;}
case 618:
-#line 3332 "gram.y"
+#line 3329 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "getpgusername";
@@ -7878,7 +7875,7 @@ case 618:
;
break;}
case 619:
-#line 3339 "gram.y"
+#line 3336 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "getpgusername";
@@ -7887,7 +7884,7 @@ case 619:
;
break;}
case 620:
-#line 3346 "gram.y"
+#line 3343 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = NIL;
@@ -7899,7 +7896,7 @@ case 620:
;
break;}
case 621:
-#line 3356 "gram.y"
+#line 3353 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "date_part";
@@ -7908,7 +7905,7 @@ case 621:
;
break;}
case 622:
-#line 3363 "gram.y"
+#line 3360 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "strpos";
@@ -7917,7 +7914,7 @@ case 622:
;
break;}
case 623:
-#line 3370 "gram.y"
+#line 3367 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "substr";
@@ -7926,7 +7923,7 @@ case 623:
;
break;}
case 624:
-#line 3378 "gram.y"
+#line 3375 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "btrim";
@@ -7935,7 +7932,7 @@ case 624:
;
break;}
case 625:
-#line 3385 "gram.y"
+#line 3382 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "ltrim";
@@ -7944,7 +7941,7 @@ case 625:
;
break;}
case 626:
-#line 3392 "gram.y"
+#line 3389 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "rtrim";
@@ -7953,7 +7950,7 @@ case 626:
;
break;}
case 627:
-#line 3399 "gram.y"
+#line 3396 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "btrim";
@@ -7962,23 +7959,23 @@ case 627:
;
break;}
case 628:
-#line 3406 "gram.y"
+#line 3403 "gram.y"
{ yyval.node = makeA_Expr(ISNULL, NULL, yyvsp[-1].node, NULL); ;
break;}
case 629:
-#line 3408 "gram.y"
+#line 3405 "gram.y"
{ yyval.node = makeA_Expr(ISNULL, NULL, yyvsp[-2].node, NULL); ;
break;}
case 630:
-#line 3410 "gram.y"
+#line 3407 "gram.y"
{ yyval.node = makeA_Expr(NOTNULL, NULL, yyvsp[-1].node, NULL); ;
break;}
case 631:
-#line 3412 "gram.y"
+#line 3409 "gram.y"
{ yyval.node = makeA_Expr(NOTNULL, NULL, yyvsp[-3].node, NULL); ;
break;}
case 632:
-#line 3419 "gram.y"
+#line 3416 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -7990,7 +7987,7 @@ case 632:
;
break;}
case 633:
-#line 3429 "gram.y"
+#line 3426 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -8002,7 +7999,7 @@ case 633:
;
break;}
case 634:
-#line 3439 "gram.y"
+#line 3436 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -8014,7 +8011,7 @@ case 634:
;
break;}
case 635:
-#line 3449 "gram.y"
+#line 3446 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -8026,7 +8023,7 @@ case 635:
;
break;}
case 636:
-#line 3459 "gram.y"
+#line 3456 "gram.y"
{
yyval.node = makeA_Expr(AND, NULL,
makeA_Expr(OP, ">=", yyvsp[-4].node, yyvsp[-2].node),
@@ -8034,7 +8031,7 @@ case 636:
;
break;}
case 637:
-#line 3465 "gram.y"
+#line 3462 "gram.y"
{
yyval.node = makeA_Expr(OR, NULL,
makeA_Expr(OP, "<", yyvsp[-5].node, yyvsp[-2].node),
@@ -8042,11 +8039,11 @@ case 637:
;
break;}
case 638:
-#line 3470 "gram.y"
+#line 3467 "gram.y"
{ saved_In_Expr = lcons(yyvsp[-1].node,saved_In_Expr); ;
break;}
case 639:
-#line 3471 "gram.y"
+#line 3468 "gram.y"
{
saved_In_Expr = lnext(saved_In_Expr);
if (nodeTag(yyvsp[-1].node) == T_SubLink)
@@ -8062,11 +8059,11 @@ case 639:
;
break;}
case 640:
-#line 3484 "gram.y"
+#line 3481 "gram.y"
{ saved_In_Expr = lcons(yyvsp[-2].node,saved_In_Expr); ;
break;}
case 641:
-#line 3485 "gram.y"
+#line 3482 "gram.y"
{
saved_In_Expr = lnext(saved_In_Expr);
if (nodeTag(yyvsp[-1].node) == T_SubLink)
@@ -8082,7 +8079,7 @@ case 641:
;
break;}
case 642:
-#line 3499 "gram.y"
+#line 3496 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8094,7 +8091,7 @@ case 642:
;
break;}
case 643:
-#line 3509 "gram.y"
+#line 3506 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8106,7 +8103,7 @@ case 643:
;
break;}
case 644:
-#line 3519 "gram.y"
+#line 3516 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8118,7 +8115,7 @@ case 644:
;
break;}
case 645:
-#line 3529 "gram.y"
+#line 3526 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8130,7 +8127,7 @@ case 645:
;
break;}
case 646:
-#line 3539 "gram.y"
+#line 3536 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8142,7 +8139,7 @@ case 646:
;
break;}
case 647:
-#line 3549 "gram.y"
+#line 3546 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8154,7 +8151,7 @@ case 647:
;
break;}
case 648:
-#line 3559 "gram.y"
+#line 3556 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8166,7 +8163,7 @@ case 648:
;
break;}
case 649:
-#line 3569 "gram.y"
+#line 3566 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-4].node, NULL);
@@ -8178,7 +8175,7 @@ case 649:
;
break;}
case 650:
-#line 3579 "gram.y"
+#line 3576 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8190,7 +8187,7 @@ case 650:
;
break;}
case 651:
-#line 3589 "gram.y"
+#line 3586 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8202,7 +8199,7 @@ case 651:
;
break;}
case 652:
-#line 3599 "gram.y"
+#line 3596 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8214,7 +8211,7 @@ case 652:
;
break;}
case 653:
-#line 3609 "gram.y"
+#line 3606 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8226,7 +8223,7 @@ case 653:
;
break;}
case 654:
-#line 3619 "gram.y"
+#line 3616 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8238,7 +8235,7 @@ case 654:
;
break;}
case 655:
-#line 3629 "gram.y"
+#line 3626 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8250,7 +8247,7 @@ case 655:
;
break;}
case 656:
-#line 3639 "gram.y"
+#line 3636 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8262,7 +8259,7 @@ case 656:
;
break;}
case 657:
-#line 3649 "gram.y"
+#line 3646 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node,NIL);
@@ -8274,7 +8271,7 @@ case 657:
;
break;}
case 658:
-#line 3659 "gram.y"
+#line 3656 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8286,7 +8283,7 @@ case 658:
;
break;}
case 659:
-#line 3669 "gram.y"
+#line 3666 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8298,7 +8295,7 @@ case 659:
;
break;}
case 660:
-#line 3679 "gram.y"
+#line 3676 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8310,7 +8307,7 @@ case 660:
;
break;}
case 661:
-#line 3689 "gram.y"
+#line 3686 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8322,7 +8319,7 @@ case 661:
;
break;}
case 662:
-#line 3699 "gram.y"
+#line 3696 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8334,7 +8331,7 @@ case 662:
;
break;}
case 663:
-#line 3709 "gram.y"
+#line 3706 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8346,7 +8343,7 @@ case 663:
;
break;}
case 664:
-#line 3719 "gram.y"
+#line 3716 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8358,7 +8355,7 @@ case 664:
;
break;}
case 665:
-#line 3729 "gram.y"
+#line 3726 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->lefthand = lcons(yyvsp[-5].node, NULL);
@@ -8370,30 +8367,30 @@ case 665:
;
break;}
case 666:
-#line 3739 "gram.y"
+#line 3736 "gram.y"
{ yyval.node = makeA_Expr(AND, NULL, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 667:
-#line 3741 "gram.y"
+#line 3738 "gram.y"
{ yyval.node = makeA_Expr(OR, NULL, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 668:
-#line 3743 "gram.y"
+#line 3740 "gram.y"
{ yyval.node = makeA_Expr(NOT, NULL, NULL, yyvsp[0].node); ;
break;}
case 669:
-#line 3753 "gram.y"
+#line 3750 "gram.y"
{
yyvsp[-1].attr->indirection = yyvsp[0].list;
yyval.node = (Node *)yyvsp[-1].attr;
;
break;}
case 670:
-#line 3758 "gram.y"
+#line 3755 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 671:
-#line 3760 "gram.y"
+#line 3757 "gram.y"
{
/* could be a column name or a relation_name */
Ident *n = makeNode(Ident);
@@ -8403,39 +8400,39 @@ case 671:
;
break;}
case 672:
-#line 3768 "gram.y"
+#line 3765 "gram.y"
{ yyval.node = makeA_Expr(OP, "-", NULL, yyvsp[0].node); ;
break;}
case 673:
-#line 3770 "gram.y"
+#line 3767 "gram.y"
{ yyval.node = makeA_Expr(OP, "+", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 674:
-#line 3772 "gram.y"
+#line 3769 "gram.y"
{ yyval.node = makeA_Expr(OP, "-", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 675:
-#line 3774 "gram.y"
+#line 3771 "gram.y"
{ yyval.node = makeA_Expr(OP, "/", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 676:
-#line 3776 "gram.y"
+#line 3773 "gram.y"
{ yyval.node = makeA_Expr(OP, "*", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 677:
-#line 3778 "gram.y"
+#line 3775 "gram.y"
{ yyval.node = makeA_Expr(OP, ":", NULL, yyvsp[0].node); ;
break;}
case 678:
-#line 3780 "gram.y"
+#line 3777 "gram.y"
{ yyval.node = makeA_Expr(OP, ";", NULL, yyvsp[0].node); ;
break;}
case 679:
-#line 3782 "gram.y"
+#line 3779 "gram.y"
{ yyval.node = makeA_Expr(OP, "|", NULL, yyvsp[0].node); ;
break;}
case 680:
-#line 3784 "gram.y"
+#line 3781 "gram.y"
{
yyval.node = (Node *)yyvsp[-2].node;
/* AexprConst can be either A_Const or ParamNo */
@@ -8453,7 +8450,7 @@ case 680:
;
break;}
case 681:
-#line 3800 "gram.y"
+#line 3797 "gram.y"
{
yyval.node = (Node *)yyvsp[-3].node;
/* AexprConst can be either A_Const or ParamNo */
@@ -8471,23 +8468,23 @@ case 681:
;
break;}
case 682:
-#line 3816 "gram.y"
+#line 3813 "gram.y"
{ yyval.node = yyvsp[-1].node; ;
break;}
case 683:
-#line 3818 "gram.y"
+#line 3815 "gram.y"
{ yyval.node = makeIndexable(yyvsp[-1].str,yyvsp[-2].node,yyvsp[0].node); ;
break;}
case 684:
-#line 3820 "gram.y"
+#line 3817 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[-1].str, NULL, yyvsp[0].node); ;
break;}
case 685:
-#line 3822 "gram.y"
+#line 3819 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[0].str, yyvsp[-1].node, NULL); ;
break;}
case 686:
-#line 3824 "gram.y"
+#line 3821 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = yyvsp[-2].str;
@@ -8496,7 +8493,7 @@ case 686:
;
break;}
case 687:
-#line 3831 "gram.y"
+#line 3828 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = yyvsp[-3].str;
@@ -8505,7 +8502,7 @@ case 687:
;
break;}
case 688:
-#line 3838 "gram.y"
+#line 3835 "gram.y"
{
A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
@@ -8522,7 +8519,7 @@ case 688:
;
break;}
case 689:
-#line 3853 "gram.y"
+#line 3850 "gram.y"
{
A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
@@ -8539,7 +8536,7 @@ case 689:
;
break;}
case 690:
-#line 3868 "gram.y"
+#line 3865 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
A_Const *s = makeNode(A_Const);
@@ -8563,7 +8560,7 @@ case 690:
;
break;}
case 691:
-#line 3890 "gram.y"
+#line 3887 "gram.y"
{
A_Const *n = makeNode(A_Const);
TypeName *t = makeNode(TypeName);
@@ -8580,7 +8577,7 @@ case 691:
;
break;}
case 692:
-#line 3905 "gram.y"
+#line 3902 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
A_Const *s = makeNode(A_Const);
@@ -8604,7 +8601,7 @@ case 692:
;
break;}
case 693:
-#line 3927 "gram.y"
+#line 3924 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "getpgusername";
@@ -8613,7 +8610,7 @@ case 693:
;
break;}
case 694:
-#line 3934 "gram.y"
+#line 3931 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "getpgusername";
@@ -8622,7 +8619,7 @@ case 694:
;
break;}
case 695:
-#line 3941 "gram.y"
+#line 3938 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "strpos";
@@ -8631,7 +8628,7 @@ case 695:
;
break;}
case 696:
-#line 3948 "gram.y"
+#line 3945 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "substr";
@@ -8640,7 +8637,7 @@ case 696:
;
break;}
case 697:
-#line 3956 "gram.y"
+#line 3953 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "btrim";
@@ -8649,7 +8646,7 @@ case 697:
;
break;}
case 698:
-#line 3963 "gram.y"
+#line 3960 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "ltrim";
@@ -8658,7 +8655,7 @@ case 698:
;
break;}
case 699:
-#line 3970 "gram.y"
+#line 3967 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "rtrim";
@@ -8667,7 +8664,7 @@ case 699:
;
break;}
case 700:
-#line 3977 "gram.y"
+#line 3974 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "btrim";
@@ -8676,7 +8673,7 @@ case 700:
;
break;}
case 701:
-#line 3986 "gram.y"
+#line 3983 "gram.y"
{
A_Indices *ai = makeNode(A_Indices);
ai->lidx = NULL;
@@ -8685,7 +8682,7 @@ case 701:
;
break;}
case 702:
-#line 3993 "gram.y"
+#line 3990 "gram.y"
{
A_Indices *ai = makeNode(A_Indices);
ai->lidx = yyvsp[-4].node;
@@ -8694,23 +8691,23 @@ case 702:
;
break;}
case 703:
-#line 4000 "gram.y"
+#line 3997 "gram.y"
{ yyval.list = NIL; ;
break;}
case 704:
-#line 4004 "gram.y"
+#line 4001 "gram.y"
{ yyval.list = lcons(yyvsp[0].node, NIL); ;
break;}
case 705:
-#line 4006 "gram.y"
+#line 4003 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, yyvsp[0].node); ;
break;}
case 706:
-#line 4008 "gram.y"
+#line 4005 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, yyvsp[0].node); ;
break;}
case 707:
-#line 4012 "gram.y"
+#line 4009 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -8719,66 +8716,66 @@ case 707:
;
break;}
case 708:
-#line 4019 "gram.y"
+#line 4016 "gram.y"
{ yyval.list = NIL; ;
break;}
case 709:
-#line 4022 "gram.y"
+#line 4019 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 710:
-#line 4023 "gram.y"
+#line 4020 "gram.y"
{ yyval.str = "tz_hour"; ;
break;}
case 711:
-#line 4024 "gram.y"
+#line 4021 "gram.y"
{ yyval.str = "tz_minute"; ;
break;}
case 712:
-#line 4028 "gram.y"
+#line 4025 "gram.y"
{ yyval.list = makeList(yyvsp[0].node, yyvsp[-2].node, -1); ;
break;}
case 713:
-#line 4030 "gram.y"
+#line 4027 "gram.y"
{ yyval.list = NIL; ;
break;}
case 714:
-#line 4034 "gram.y"
+#line 4031 "gram.y"
{
yyvsp[-1].attr->indirection = yyvsp[0].list;
yyval.node = (Node *)yyvsp[-1].attr;
;
break;}
case 715:
-#line 4039 "gram.y"
+#line 4036 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 716:
-#line 4041 "gram.y"
+#line 4038 "gram.y"
{ yyval.node = makeA_Expr(OP, "-", NULL, yyvsp[0].node); ;
break;}
case 717:
-#line 4043 "gram.y"
+#line 4040 "gram.y"
{ yyval.node = makeA_Expr(OP, "+", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 718:
-#line 4045 "gram.y"
+#line 4042 "gram.y"
{ yyval.node = makeA_Expr(OP, "-", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 719:
-#line 4047 "gram.y"
+#line 4044 "gram.y"
{ yyval.node = makeA_Expr(OP, "/", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 720:
-#line 4049 "gram.y"
+#line 4046 "gram.y"
{ yyval.node = makeA_Expr(OP, "*", yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 721:
-#line 4051 "gram.y"
+#line 4048 "gram.y"
{ yyval.node = makeA_Expr(OP, "|", NULL, yyvsp[0].node); ;
break;}
case 722:
-#line 4053 "gram.y"
+#line 4050 "gram.y"
{
yyval.node = (Node *)yyvsp[-2].node;
/* AexprConst can be either A_Const or ParamNo */
@@ -8796,7 +8793,7 @@ case 722:
;
break;}
case 723:
-#line 4069 "gram.y"
+#line 4066 "gram.y"
{
yyval.node = (Node *)yyvsp[-3].node;
/* AexprConst can be either A_Const or ParamNo */
@@ -8814,23 +8811,23 @@ case 723:
;
break;}
case 724:
-#line 4085 "gram.y"
+#line 4082 "gram.y"
{ yyval.node = yyvsp[-1].node; ;
break;}
case 725:
-#line 4087 "gram.y"
+#line 4084 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[-1].str, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 726:
-#line 4089 "gram.y"
+#line 4086 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[-1].str, NULL, yyvsp[0].node); ;
break;}
case 727:
-#line 4091 "gram.y"
+#line 4088 "gram.y"
{ yyval.node = makeA_Expr(OP, yyvsp[0].str, yyvsp[-1].node, NULL); ;
break;}
case 728:
-#line 4093 "gram.y"
+#line 4090 "gram.y"
{
/* could be a column name or a relation_name */
Ident *n = makeNode(Ident);
@@ -8840,7 +8837,7 @@ case 728:
;
break;}
case 729:
-#line 4101 "gram.y"
+#line 4098 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = yyvsp[-2].str;
@@ -8849,7 +8846,7 @@ case 729:
;
break;}
case 730:
-#line 4108 "gram.y"
+#line 4105 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = yyvsp[-3].str;
@@ -8858,7 +8855,7 @@ case 730:
;
break;}
case 731:
-#line 4115 "gram.y"
+#line 4112 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "strpos";
@@ -8867,7 +8864,7 @@ case 731:
;
break;}
case 732:
-#line 4122 "gram.y"
+#line 4119 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "substr";
@@ -8876,7 +8873,7 @@ case 732:
;
break;}
case 733:
-#line 4130 "gram.y"
+#line 4127 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "btrim";
@@ -8885,7 +8882,7 @@ case 733:
;
break;}
case 734:
-#line 4137 "gram.y"
+#line 4134 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "ltrim";
@@ -8894,7 +8891,7 @@ case 734:
;
break;}
case 735:
-#line 4144 "gram.y"
+#line 4141 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "rtrim";
@@ -8903,7 +8900,7 @@ case 735:
;
break;}
case 736:
-#line 4151 "gram.y"
+#line 4148 "gram.y"
{
FuncCall *n = makeNode(FuncCall);
n->funcname = "btrim";
@@ -8912,21 +8909,21 @@ case 736:
;
break;}
case 737:
-#line 4160 "gram.y"
+#line 4157 "gram.y"
{
yyval.list = nconc(nconc(yyvsp[-2].list,yyvsp[-1].list),yyvsp[0].list);
;
break;}
case 738:
-#line 4164 "gram.y"
+#line 4161 "gram.y"
{ yyval.list = NIL; ;
break;}
case 739:
-#line 4168 "gram.y"
+#line 4165 "gram.y"
{ yyval.list = yyvsp[0].list; ;
break;}
case 740:
-#line 4170 "gram.y"
+#line 4167 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
@@ -8935,27 +8932,27 @@ case 740:
;
break;}
case 741:
-#line 4179 "gram.y"
+#line 4176 "gram.y"
{ yyval.list = yyvsp[0].list; ;
break;}
case 742:
-#line 4181 "gram.y"
+#line 4178 "gram.y"
{ yyval.list = NIL; ;
break;}
case 743:
-#line 4185 "gram.y"
+#line 4182 "gram.y"
{ yyval.list = lappend(yyvsp[0].list, yyvsp[-2].node); ;
break;}
case 744:
-#line 4187 "gram.y"
+#line 4184 "gram.y"
{ yyval.list = yyvsp[0].list; ;
break;}
case 745:
-#line 4189 "gram.y"
+#line 4186 "gram.y"
{ yyval.list = yyvsp[0].list; ;
break;}
case 746:
-#line 4193 "gram.y"
+#line 4190 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->subselect = yyvsp[0].node;
@@ -8963,21 +8960,21 @@ case 746:
;
break;}
case 747:
-#line 4199 "gram.y"
+#line 4196 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 748:
-#line 4203 "gram.y"
+#line 4200 "gram.y"
{ yyval.node = makeA_Expr(OP, "=", lfirst(saved_In_Expr), yyvsp[0].node); ;
break;}
case 749:
-#line 4205 "gram.y"
+#line 4202 "gram.y"
{ yyval.node = makeA_Expr(OR, NULL, yyvsp[-2].node,
makeA_Expr(OP, "=", lfirst(saved_In_Expr), yyvsp[0].node));
;
break;}
case 750:
-#line 4211 "gram.y"
+#line 4208 "gram.y"
{
SubLink *n = makeNode(SubLink);
n->subselect = yyvsp[0].node;
@@ -8985,21 +8982,21 @@ case 750:
;
break;}
case 751:
-#line 4217 "gram.y"
+#line 4214 "gram.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 752:
-#line 4221 "gram.y"
+#line 4218 "gram.y"
{ yyval.node = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), yyvsp[0].node); ;
break;}
case 753:
-#line 4223 "gram.y"
+#line 4220 "gram.y"
{ yyval.node = makeA_Expr(AND, NULL, yyvsp[-2].node,
makeA_Expr(OP, "<>", lfirst(saved_In_Expr), yyvsp[0].node));
;
break;}
case 754:
-#line 4229 "gram.y"
+#line 4226 "gram.y"
{
yyval.attr = makeNode(Attr);
yyval.attr->relname = yyvsp[-2].str;
@@ -9009,7 +9006,7 @@ case 754:
;
break;}
case 755:
-#line 4237 "gram.y"
+#line 4234 "gram.y"
{
yyval.attr = makeNode(Attr);
yyval.attr->relname = NULL;
@@ -9019,27 +9016,27 @@ case 755:
;
break;}
case 756:
-#line 4247 "gram.y"
+#line 4244 "gram.y"
{ yyval.list = lcons(makeString(yyvsp[0].str), NIL); ;
break;}
case 757:
-#line 4249 "gram.y"
+#line 4246 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, makeString(yyvsp[0].str)); ;
break;}
case 758:
-#line 4251 "gram.y"
+#line 4248 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, makeString("*")); ;
break;}
case 759:
-#line 4262 "gram.y"
+#line 4259 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list,yyvsp[0].target); ;
break;}
case 760:
-#line 4264 "gram.y"
+#line 4261 "gram.y"
{ yyval.list = lcons(yyvsp[0].target, NIL); ;
break;}
case 761:
-#line 4266 "gram.y"
+#line 4263 "gram.y"
{
ResTarget *rt = makeNode(ResTarget);
Attr *att = makeNode(Attr);
@@ -9054,7 +9051,7 @@ case 761:
;
break;}
case 762:
-#line 4281 "gram.y"
+#line 4278 "gram.y"
{
yyval.target = makeNode(ResTarget);
yyval.target->name = yyvsp[-3].str;
@@ -9063,7 +9060,7 @@ case 762:
;
break;}
case 763:
-#line 4288 "gram.y"
+#line 4285 "gram.y"
{
yyval.target = makeNode(ResTarget);
yyval.target->name = NULL;
@@ -9072,7 +9069,7 @@ case 763:
;
break;}
case 764:
-#line 4295 "gram.y"
+#line 4292 "gram.y"
{
Attr *att = makeNode(Attr);
att->relname = yyvsp[-2].str;
@@ -9086,15 +9083,15 @@ case 764:
;
break;}
case 765:
-#line 4314 "gram.y"
+#line 4311 "gram.y"
{ yyval.list = lappend(yyvsp[-2].list, yyvsp[0].target); ;
break;}
case 766:
-#line 4316 "gram.y"
+#line 4313 "gram.y"
{ yyval.list = lcons(yyvsp[0].target, NIL); ;
break;}
case 767:
-#line 4321 "gram.y"
+#line 4318 "gram.y"
{
yyval.target = makeNode(ResTarget);
yyval.target->name = yyvsp[0].str;
@@ -9103,7 +9100,7 @@ case 767:
;
break;}
case 768:
-#line 4328 "gram.y"
+#line 4325 "gram.y"
{
yyval.target = makeNode(ResTarget);
yyval.target->name = NULL;
@@ -9112,7 +9109,7 @@ case 768:
;
break;}
case 769:
-#line 4335 "gram.y"
+#line 4332 "gram.y"
{
Attr *att = makeNode(Attr);
att->relname = yyvsp[-2].str;
@@ -9126,7 +9123,7 @@ case 769:
;
break;}
case 770:
-#line 4347 "gram.y"
+#line 4344 "gram.y"
{
Attr *att = makeNode(Attr);
att->relname = "*";
@@ -9140,22 +9137,22 @@ case 770:
;
break;}
case 771:
-#line 4360 "gram.y"
+#line 4357 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 772:
-#line 4361 "gram.y"
+#line 4358 "gram.y"
{ yyval.str = NULL; ;
break;}
case 773:
-#line 4365 "gram.y"
+#line 4362 "gram.y"
{
yyval.str = yyvsp[0].str;
StrNCpy(saved_relname, yyvsp[0].str, NAMEDATALEN);
;
break;}
case 774:
-#line 4370 "gram.y"
+#line 4367 "gram.y"
{
/* disallow refs to variable system tables */
if (strcmp(LogRelationName, yyvsp[0].str) == 0
@@ -9167,43 +9164,43 @@ case 774:
;
break;}
case 775:
-#line 4381 "gram.y"
+#line 4378 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 776:
-#line 4382 "gram.y"
+#line 4379 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 777:
-#line 4383 "gram.y"
+#line 4380 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 778:
-#line 4384 "gram.y"
+#line 4381 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 779:
-#line 4385 "gram.y"
+#line 4382 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 780:
-#line 4391 "gram.y"
+#line 4388 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 781:
-#line 4392 "gram.y"
+#line 4389 "gram.y"
{ yyval.str = xlateSqlFunc(yyvsp[0].str); ;
break;}
case 782:
-#line 4394 "gram.y"
+#line 4391 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 783:
-#line 4395 "gram.y"
+#line 4392 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 784:
-#line 4401 "gram.y"
+#line 4398 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
@@ -9212,7 +9209,7 @@ case 784:
;
break;}
case 785:
-#line 4408 "gram.y"
+#line 4405 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Float;
@@ -9221,7 +9218,7 @@ case 785:
;
break;}
case 786:
-#line 4415 "gram.y"
+#line 4412 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -9230,7 +9227,7 @@ case 786:
;
break;}
case 787:
-#line 4422 "gram.y"
+#line 4419 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->typename = yyvsp[-1].typnam;
@@ -9240,11 +9237,11 @@ case 787:
;
break;}
case 788:
-#line 4430 "gram.y"
+#line 4427 "gram.y"
{ yyval.node = (Node *)yyvsp[0].paramno; ;
break;}
case 789:
-#line 4432 "gram.y"
+#line 4429 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -9256,7 +9253,7 @@ case 789:
;
break;}
case 790:
-#line 4442 "gram.y"
+#line 4439 "gram.y"
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
@@ -9268,234 +9265,234 @@ case 790:
;
break;}
case 791:
-#line 4454 "gram.y"
+#line 4451 "gram.y"
{
yyval.paramno = makeNode(ParamNo);
yyval.paramno->number = yyvsp[0].ival;
;
break;}
case 792:
-#line 4460 "gram.y"
+#line 4457 "gram.y"
{ yyval.ival = yyvsp[0].ival; ;
break;}
case 793:
-#line 4461 "gram.y"
+#line 4458 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 794:
-#line 4462 "gram.y"
+#line 4459 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 795:
-#line 4470 "gram.y"
+#line 4467 "gram.y"
{ yyval.str = xlateSqlType(yyvsp[0].str); ;
break;}
case 796:
-#line 4472 "gram.y"
+#line 4469 "gram.y"
{ yyval.str = xlateSqlType(yyvsp[0].str); ;
break;}
case 797:
-#line 4474 "gram.y"
+#line 4471 "gram.y"
{ yyval.str = xlateSqlType(yyvsp[0].str); ;
break;}
case 798:
-#line 4484 "gram.y"
+#line 4481 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 799:
-#line 4485 "gram.y"
+#line 4482 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 800:
-#line 4486 "gram.y"
+#line 4483 "gram.y"
{ yyval.str = "action"; ;
break;}
case 801:
-#line 4487 "gram.y"
+#line 4484 "gram.y"
{ yyval.str = "cache"; ;
break;}
case 802:
-#line 4488 "gram.y"
+#line 4485 "gram.y"
{ yyval.str = "cycle"; ;
break;}
case 803:
-#line 4489 "gram.y"
+#line 4486 "gram.y"
{ yyval.str = "database"; ;
break;}
case 804:
-#line 4490 "gram.y"
+#line 4487 "gram.y"
{ yyval.str = "delimiters"; ;
break;}
case 805:
-#line 4491 "gram.y"
+#line 4488 "gram.y"
{ yyval.str = "double"; ;
break;}
case 806:
-#line 4492 "gram.y"
+#line 4489 "gram.y"
{ yyval.str = "each"; ;
break;}
case 807:
-#line 4493 "gram.y"
+#line 4490 "gram.y"
{ yyval.str = "function"; ;
break;}
case 808:
-#line 4494 "gram.y"
+#line 4491 "gram.y"
{ yyval.str = "increment"; ;
break;}
case 809:
-#line 4495 "gram.y"
+#line 4492 "gram.y"
{ yyval.str = "index"; ;
break;}
case 810:
-#line 4496 "gram.y"
+#line 4493 "gram.y"
{ yyval.str = "key"; ;
break;}
case 811:
-#line 4497 "gram.y"
+#line 4494 "gram.y"
{ yyval.str = "language"; ;
break;}
case 812:
-#line 4498 "gram.y"
+#line 4495 "gram.y"
{ yyval.str = "location"; ;
break;}
case 813:
-#line 4499 "gram.y"
+#line 4496 "gram.y"
{ yyval.str = "match"; ;
break;}
case 814:
-#line 4500 "gram.y"
+#line 4497 "gram.y"
{ yyval.str = "maxvalue"; ;
break;}
case 815:
-#line 4501 "gram.y"
+#line 4498 "gram.y"
{ yyval.str = "minvalue"; ;
break;}
case 816:
-#line 4502 "gram.y"
+#line 4499 "gram.y"
{ yyval.str = "operator"; ;
break;}
case 817:
-#line 4503 "gram.y"
+#line 4500 "gram.y"
{ yyval.str = "option"; ;
break;}
case 818:
-#line 4504 "gram.y"
+#line 4501 "gram.y"
{ yyval.str = "password"; ;
break;}
case 819:
-#line 4505 "gram.y"
+#line 4502 "gram.y"
{ yyval.str = "privileges"; ;
break;}
case 820:
-#line 4506 "gram.y"
+#line 4503 "gram.y"
{ yyval.str = "recipe"; ;
break;}
case 821:
-#line 4507 "gram.y"
+#line 4504 "gram.y"
{ yyval.str = "row"; ;
break;}
case 822:
-#line 4508 "gram.y"
+#line 4505 "gram.y"
{ yyval.str = "start"; ;
break;}
case 823:
-#line 4509 "gram.y"
+#line 4506 "gram.y"
{ yyval.str = "statement"; ;
break;}
case 824:
-#line 4510 "gram.y"
+#line 4507 "gram.y"
{ yyval.str = "time"; ;
break;}
case 825:
-#line 4511 "gram.y"
+#line 4508 "gram.y"
{ yyval.str = "timezone_hour"; ;
break;}
case 826:
-#line 4512 "gram.y"
+#line 4509 "gram.y"
{ yyval.str = "timezone_minute"; ;
break;}
case 827:
-#line 4513 "gram.y"
+#line 4510 "gram.y"
{ yyval.str = "trigger"; ;
break;}
case 828:
-#line 4514 "gram.y"
+#line 4511 "gram.y"
{ yyval.str = "type"; ;
break;}
case 829:
-#line 4515 "gram.y"
+#line 4512 "gram.y"
{ yyval.str = "valid"; ;
break;}
case 830:
-#line 4516 "gram.y"
+#line 4513 "gram.y"
{ yyval.str = "version"; ;
break;}
case 831:
-#line 4517 "gram.y"
+#line 4514 "gram.y"
{ yyval.str = "zone"; ;
break;}
case 832:
-#line 4530 "gram.y"
+#line 4527 "gram.y"
{ yyval.str = yyvsp[0].str; ;
break;}
case 833:
-#line 4531 "gram.y"
+#line 4528 "gram.y"
{ yyval.str = "archive"; ;
break;}
case 834:
-#line 4532 "gram.y"
+#line 4529 "gram.y"
{ yyval.str = "cluster"; ;
break;}
case 835:
-#line 4533 "gram.y"
+#line 4530 "gram.y"
{ yyval.str = "constraint"; ;
break;}
case 836:
-#line 4534 "gram.y"
+#line 4531 "gram.y"
{ yyval.str = "cross"; ;
break;}
case 837:
-#line 4535 "gram.y"
+#line 4532 "gram.y"
{ yyval.str = "foreign"; ;
break;}
case 838:
-#line 4536 "gram.y"
+#line 4533 "gram.y"
{ yyval.str = "group"; ;
break;}
case 839:
-#line 4537 "gram.y"
+#line 4534 "gram.y"
{ yyval.str = "load"; ;
break;}
case 840:
-#line 4538 "gram.y"
+#line 4535 "gram.y"
{ yyval.str = "order"; ;
break;}
case 841:
-#line 4539 "gram.y"
+#line 4536 "gram.y"
{ yyval.str = "position"; ;
break;}
case 842:
-#line 4540 "gram.y"
+#line 4537 "gram.y"
{ yyval.str = "precision"; ;
break;}
case 843:
-#line 4541 "gram.y"
+#line 4538 "gram.y"
{ yyval.str = "table"; ;
break;}
case 844:
-#line 4542 "gram.y"
+#line 4539 "gram.y"
{ yyval.str = "transaction"; ;
break;}
case 845:
-#line 4543 "gram.y"
+#line 4540 "gram.y"
{ yyval.str = "true"; ;
break;}
case 846:
-#line 4544 "gram.y"
+#line 4541 "gram.y"
{ yyval.str = "false"; ;
break;}
case 847:
-#line 4548 "gram.y"
+#line 4545 "gram.y"
{
if (QueryIsRule)
yyval.str = "*CURRENT*";
@@ -9504,7 +9501,7 @@ case 847:
;
break;}
case 848:
-#line 4555 "gram.y"
+#line 4552 "gram.y"
{
if (QueryIsRule)
yyval.str = "*NEW*";
@@ -9710,7 +9707,7 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
}
-#line 4563 "gram.y"
+#line 4560 "gram.y"
static Node *
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index df4acded9ae..71d4a204c65 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.14 1998/07/15 15:56:36 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.15 1998/07/19 05:49:22 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -2574,9 +2574,6 @@ groupby: ColId
having_clause: HAVING a_expr
{
-#if FALSE
- elog(ERROR,"HAVING clause not yet implemented");
-#endif
$$ = $2;
}
| /*EMPTY*/ { $$ = NULL; }
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index 97c468a9389..aff40937edb 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.16 1998/06/15 19:29:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.17 1998/07/19 05:49:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -342,23 +342,41 @@ ApplyRetrieveRule(Query *parsetree,
OffsetVarNodes(rule_action->qual, rt_length);
OffsetVarNodes((Node *) rule_action->targetList, rt_length);
OffsetVarNodes(rule_qual, rt_length);
+
+ OffsetVarNodes((Node *) rule_action->groupClause, rt_length);
+ OffsetVarNodes((Node *) rule_action->havingQual, rt_length);
+
ChangeVarNodes(rule_action->qual,
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
ChangeVarNodes((Node *) rule_action->targetList,
PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
ChangeVarNodes(rule_qual, PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
+
+ ChangeVarNodes((Node *) rule_action->groupClause,
+ PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
+ ChangeVarNodes((Node *) rule_action->havingQual,
+ PRS2_CURRENT_VARNO + rt_length, rt_index, 0);
+
if (relation_level)
{
- HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
- modified);
+ HandleViewRule(parsetree, rtable, rule_action->targetList, rt_index,
+ modified);
}
else
{
- HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
- rt_index, rule->attrno, modified, &badsql);
+ HandleRIRAttributeRule(parsetree, rtable, rule_action->targetList,
+ rt_index, rule->attrno, modified, &badsql);
}
- if (*modified && !badsql)
- AddQual(parsetree, rule_action->qual);
+ if (*modified && !badsql) {
+ AddQual(parsetree, rule_action->qual);
+ /* This will only work if the query made to the view defined by the following
+ * groupClause groups by the same attributes or does not use group at all! */
+ if (parsetree->groupClause == NULL)
+ parsetree->groupClause=rule_action->groupClause;
+ AddHavingQual(parsetree, rule_action->havingQual);
+ parsetree->hasAggs = (rule_action->hasAggs || parsetree->hasAggs);
+ parsetree->hasSubLinks = (rule_action->hasSubLinks || parsetree->hasSubLinks);
+ }
}
static List *
@@ -680,6 +698,8 @@ List *
QueryRewrite(Query *parsetree)
{
QueryRewriteSubLink(parsetree->qual);
+ QueryRewriteSubLink(parsetree->havingQual);
+
return QueryRewriteOne(parsetree);
}
@@ -730,6 +750,8 @@ QueryRewriteSubLink(Node *node)
* SubLink we don't process it as part of this loop.
*/
QueryRewriteSubLink((Node *) query->qual);
+
+ QueryRewriteSubLink((Node *) query->havingQual);
ret = QueryRewriteOne(query);
if (!ret)
diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c
index 0c124a36389..7606698afdf 100644
--- a/src/backend/rewrite/rewriteManip.c
+++ b/src/backend/rewrite/rewriteManip.c
@@ -6,7 +6,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.14 1998/06/15 19:29:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.15 1998/07/19 05:49:24 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,6 +55,14 @@ OffsetVarNodes(Node *node, int offset)
OffsetVarNodes(agg->target, offset);
}
break;
+ /* This has to be done to make queries using groupclauses work on views */
+ case T_GroupClause:
+ {
+ GroupClause *group = (GroupClause *) node;
+
+ OffsetVarNodes((Node *)(group->entry), offset);
+ }
+ break;
case T_Expr:
{
Expr *expr = (Expr *) node;
@@ -78,6 +86,22 @@ OffsetVarNodes(Node *node, int offset)
OffsetVarNodes(lfirst(l), offset);
}
break;
+ case T_SubLink:
+ {
+ SubLink *sublink = (SubLink *) node;
+
+ /* We also have to adapt the variables used in sublink->lefthand
+ * and sublink->oper */
+ OffsetVarNodes((Node *)(sublink->lefthand), offset);
+
+ /* Make sure the first argument of sublink->oper points to the
+ * same var as sublink->lefthand does otherwise we will
+ * run into troubles using aggregates (aggno will not be
+ * set correctly) */
+ lfirst(((Expr *) lfirst(sublink->oper))->args) =
+ lfirst(sublink->lefthand);
+ }
+ break;
default:
/* ignore the others */
break;
@@ -105,6 +129,16 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
ChangeVarNodes(agg->target, old_varno, new_varno, sublevels_up);
}
break;
+ /* This has to be done to make queries using groupclauses work on views */
+ case T_GroupClause:
+ {
+ GroupClause *group = (GroupClause *) node;
+
+ ChangeVarNodes((Node *)(group->entry),old_varno, new_varno,
+ sublevels_up);
+ }
+ break;
+
case T_Expr:
{
Expr *expr = (Expr *) node;
@@ -122,6 +156,8 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
var->varno = new_varno;
var->varnoold = new_varno;
}
+ if (var->varlevelsup > 0) OffsetVarNodes((Node *)var,3);
+
}
break;
case T_List:
@@ -139,6 +175,18 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno, int sublevels_up)
ChangeVarNodes((Node *) query->qual, old_varno, new_varno,
sublevels_up + 1);
+
+ /* We also have to adapt the variables used in sublink->lefthand
+ * and sublink->oper */
+ ChangeVarNodes((Node *) (sublink->lefthand), old_varno, new_varno,
+ sublevels_up);
+
+ /* Make sure the first argument of sublink->oper points to the
+ * same var as sublink->lefthand does otherwise we will
+ * run into troubles using aggregates (aggno will not be
+ * set correctly */
+ /* lfirst(((Expr *) lfirst(sublink->oper))->args) =
+ lfirst(sublink->lefthand); */
}
break;
default:
@@ -165,6 +213,26 @@ AddQual(Query *parsetree, Node *qual)
(Node *) make_andclause(makeList(parsetree->qual, copy, -1));
}
+/* Adds the given havingQual to the one already contained in the parsetree just as
+ * AddQual does for the normal 'where' qual */
+void
+AddHavingQual(Query *parsetree, Node *havingQual)
+{
+ Node *copy, *old;
+
+ if (havingQual == NULL)
+ return;
+
+ copy = copyObject(havingQual);
+ old = parsetree->havingQual;
+ if (old == NULL)
+ parsetree->havingQual = copy;
+ else
+ parsetree->havingQual =
+ (Node *) make_andclause(makeList(parsetree->havingQual, copy, -1));
+}
+
+
void
AddNotQual(Query *parsetree, Node *qual)
{
@@ -485,9 +553,18 @@ nodeHandleViewRule(Node **nodePtr,
Aggreg *agg = (Aggreg *) node;
nodeHandleViewRule(&(agg->target), rtable, targetlist,
- rt_index, modified, sublevels_up);
+ rt_index, modified, sublevels_up);
}
break;
+ /* This has to be done to make queries using groupclauses work on views */
+ case T_GroupClause:
+ {
+ GroupClause *group = (GroupClause *) node;
+
+ nodeHandleViewRule((Node **) (&(group->entry)), rtable, targetlist,
+ rt_index, modified, sublevels_up);
+ }
+ break;
case T_Expr:
{
Expr *expr = (Expr *) node;
@@ -503,20 +580,40 @@ nodeHandleViewRule(Node **nodePtr,
int this_varno = var->varno;
int this_varlevelsup = var->varlevelsup;
Node *n;
-
+
if (this_varno == rt_index &&
- this_varlevelsup == sublevels_up)
- {
- n = FindMatchingTLEntry(targetlist,
- get_attname(getrelid(this_varno,
- rtable),
- var->varattno));
- if (n == NULL)
- *nodePtr = make_null(((Var *) node)->vartype);
- else
- *nodePtr = n;
- *modified = TRUE;
- }
+ this_varlevelsup == sublevels_up)
+ {
+ n = FindMatchingTLEntry(targetlist,
+ get_attname(getrelid(this_varno,
+ rtable),
+ var->varattno));
+ if (n == NULL)
+ {
+ *nodePtr = make_null(((Var *) node)->vartype);
+ }
+
+ else
+ /* This is a hack: The varlevelsup of the orignal
+ * variable and the new one should be the same.
+ * Normally we adapt the node by changing a pointer
+ * to point to a var contained in 'targetlist'.
+ * In the targetlist all varlevelsups are 0
+ * so if we want to change it to the original value
+ * we have to copy the node before! (Maybe this will
+ * cause troubles with some sophisticated queries on
+ * views?) */
+ {
+ if(this_varlevelsup>0){
+ *nodePtr = copyObject(n);
+ }
+ else {
+ *nodePtr = n;
+ }
+ ((Var *)*nodePtr)->varlevelsup = this_varlevelsup;
+ }
+ *modified = TRUE;
+ }
break;
}
case T_List:
@@ -537,7 +634,20 @@ nodeHandleViewRule(Node **nodePtr,
Query *query = (Query *) sublink->subselect;
nodeHandleViewRule((Node **) &(query->qual), rtable, targetlist,
- rt_index, modified, sublevels_up + 1);
+ rt_index, modified, sublevels_up + 1);
+
+ /* We also have to adapt the variables used in sublink->lefthand
+ * and sublink->oper */
+ nodeHandleViewRule((Node **) &(sublink->lefthand), rtable,
+ targetlist, rt_index, modified, sublevels_up);
+
+ /* Make sure the first argument of sublink->oper points to the
+ * same var as sublink->lefthand does otherwise we will
+ * run into troubles using aggregates (aggno will not be
+ * set correctly */
+ pfree(lfirst(((Expr *) lfirst(sublink->oper))->args));
+ lfirst(((Expr *) lfirst(sublink->oper))->args) =
+ lfirst(sublink->lefthand);
}
break;
default:
@@ -553,9 +663,14 @@ HandleViewRule(Query *parsetree,
int rt_index,
int *modified)
{
-
nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
modified, 0);
nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
rt_index, modified, 0);
+ /* The variables in the havingQual and groupClause also have to be adapted */
+ nodeHandleViewRule(&parsetree->havingQual, rtable, targetlist, rt_index,
+ modified, 0);
+ nodeHandleViewRule((Node **) (&(parsetree->groupClause)), rtable, targetlist, rt_index,
+ modified, 0);
}
+
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index a80cf48e135..ab4e81f5437 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: planmain.h,v 1.12 1998/04/15 15:29:57 momjian Exp $
+ * $Id: planmain.h,v 1.13 1998/07/19 05:49:25 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -64,6 +64,8 @@ extern void set_result_tlist_references(Result *resultNode);
extern List *set_agg_tlist_references(Agg *aggNode);
extern void set_agg_agglist_references(Agg *aggNode);
extern void del_agg_tlist_references(List *tlist);
-extern List *check_having_qual_for_aggs(Node *clause, List *subplanTargetList);
+extern List *check_having_qual_for_aggs(Node *clause,
+ List *subplanTargetList, List *groupClause);
+extern List *check_having_qual_for_vars(Node *clause, List *targetlist_so_far);
#endif /* PLANMAIN_H */
diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h
index 9dbd73d2ef1..f5934a89626 100644
--- a/src/include/rewrite/rewriteManip.h
+++ b/src/include/rewrite/rewriteManip.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: rewriteManip.h,v 1.7 1998/02/26 04:43:08 momjian Exp $
+ * $Id: rewriteManip.h,v 1.8 1998/07/19 05:49:26 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -23,6 +23,8 @@ void
ChangeVarNodes(Node *node, int old_varno, int new_varno,
int sublevels_up);
void AddQual(Query *parsetree, Node *qual);
+void AddHavingQual(Query *parsetree, Node *havingQual);
+
void AddNotQual(Query *parsetree, Node *qual);
void FixResdomTypes(List *user_tlist);
void FixNew(RewriteInfo *info, Query *parsetree);