*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.26 1998/02/26 04:31:13 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.27 1998/03/30 16:35:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
static Datum
ExecEvalAggreg(Aggreg *agg, ExprContext *econtext, bool *isNull)
{
-
- *isNull = econtext->ecxt_nulls[agg->aggno];
+ *isNull = econtext->ecxt_nulls[agg->aggno];
return econtext->ecxt_values[agg->aggno];
}
econtext,
&argIsNull,
argIsDone);
+
+
if (!(*argIsDone))
{
Assert(i == 0);
* ----------------
*/
result = false;
+
foreach(clause, qual)
{
+
+
result = ExecQualClause((Node *) lfirst(clause), econtext);
if (result == true)
break;
#include "storage/bufmgr.h"
#include "utils/palloc.h"
#include "utils/syscache.h"
+#include "optimizer/clauses.h"
/*
* AggFuncInfo -
isNull1 = FALSE,
isNull2 = FALSE;
+
+ /***S*H***/
+ do {
+
+
/* ---------------------
* get state info from node
* ---------------------
*/
+
aggstate = node->aggstate;
if (aggstate->agg_done)
return NULL;
}
}
}
+
/* ----------------
* for each tuple from the the outer plan, apply all the aggregates
* slot and return it.
* ----------------
*/
+
+ /***S*H***/
+ }
+ while((ExecQual(fix_opids(node->plan.qual),econtext)!=true) &&
+ (node->plan.qual!=NULL));
+
+
ExecStoreTuple(oneTuple,
aggstate->csstate.css_ScanTupleSlot,
InvalidBuffer,
false);
econtext->ecxt_scantuple = aggstate->csstate.css_ScanTupleSlot;
+
resultSlot = ExecProject(projInfo, &isDone);
if (oneTuple)
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.23 1998/02/26 04:32:51 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.24 1998/03/30 16:36:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
*
*****************************************************************************/
+
+/***S*H***/ /* Anfang */
+
+static List *
+check_having_qual_for_aggs(Node *clause, List *subplanTargetList)
+{
+ List *t;
+ List *agg_list = NIL;
+
+ if (IsA(clause, Var))
+ {
+ TargetEntry *subplanVar;
+
+ /*
+ * Ha! A Var node!
+ */
+ subplanVar = match_varid((Var *) clause, subplanTargetList);
+
+ /*
+ * Change the varno & varattno fields of the var node.
+ *
+ */
+ ((Var *) clause)->varattno = subplanVar->resdom->resno;
+ return NIL;
+ }
+ /***S*H***/
+ 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)
+ {
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(lfirst(t), subplanTargetList));
+ }
+ return agg_list;
+ }
+ else if (IsA(clause, Aggreg))
+ {
+ return lcons(clause,
+ check_having_qual_for_aggs(((Aggreg *) clause)->target, subplanTargetList));
+
+ }
+ 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)
+ {
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(lfirst(t), subplanTargetList));
+ }
+ foreach(t, aref->reflowerindexpr)
+ {
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(lfirst(t), subplanTargetList));
+ }
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(aref->refexpr, subplanTargetList));
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(aref->refassgnexpr, subplanTargetList));
+
+ return agg_list;
+ }
+ 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)
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(left, subplanTargetList));
+ if (right != (Node *) NULL)
+ agg_list = nconc(agg_list,
+ check_having_qual_for_aggs(right, subplanTargetList));
+
+ return agg_list;
+ }
+ else if (IsA(clause, Param) ||IsA(clause, Const))
+ {
+ /* do nothing! */
+ return NIL;
+ }
+ else
+ {
+
+ /*
+ * Ooops! we can not handle that!
+ */
+ elog(ERROR, "check_having_qual_for_aggs: Can not handle this having_qual!\n");
+ return NIL;
+ }
+}
+/***S*H***/ /* Ende */
+
+
Plan *
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);
+
+ /***S*H***/
+ if(parse->havingQual!=NULL) {
+ List *clause;
+
+ /***S*H***/ /* 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));
+ }
+ }
}
/*
/* success */
return;
}
+
+
+
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.19 1998/02/26 04:32:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.20 1998/03/30 16:36:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
}
}
+
/*
* del_agg_tlist_references
* Remove the Agg nodes from the target list
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.71 1998/02/26 04:33:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.72 1998/03/30 16:36:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
qry->targetList = transformTargetList(pstate, stmt->targetList);
qry->qual = transformWhereClause(pstate, stmt->whereClause);
+
+ /***S*H***/
+ qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
+
qry->hasSubLinks = pstate->p_hasSubLinks;
qry->sortClause = transformSortClause(pstate,
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.4 1998/03/18 16:50:15 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/Attic/gram.c,v 2.5 1998/03/30 16:36:32 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
case 464:
#line 2529 "gram.y"
{
- elog(NOTICE, "HAVING not yet supported; ignore clause");
+ /***S*H***/ /* elog(NOTICE, "HAVING not yet supported; ignore clause");*/
yyval.node = yyvsp[0].node;
;
break;}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.7 1998/03/18 16:50:19 thomas Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.8 1998/03/30 16:36:35 momjian Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
having_clause: HAVING a_expr
{
- elog(NOTICE, "HAVING not yet supported; ignore clause");
+ /***S*H***/ /* elog(NOTICE, "HAVING not yet supported; ignore clause");*/
$$ = $2;
}
| /*EMPTY*/ { $$ = NULL; }
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.9 1998/02/26 04:33:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.10 1998/03/30 16:36:36 momjian Exp $
*
*-------------------------------------------------------------------------
*/
aggreg->target = lfirst(target);
if (usenulls)
aggreg->usenulls = true;
-
+
pstate->p_hasAggs = true;
return aggreg;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.14 1998/02/26 04:35:16 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.15 1998/03/30 16:36:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
if ((rt_entry_locks = relation->rd_rules) == NULL)
return NIL;
- locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
+ locks = matchLocks(CMD_SELECT, rt_entry_locks, rt_index, parsetree);
/* find all retrieve instead */
foreach(i, locks)
List *product_queries = NIL;
int rt_index = 0;
+
foreach(rt, rtable)
{
RangeTblEntry *rt_entry = lfirst(rt);
rt_index++;
rt_entry_relation = heap_openr(rt_entry->relname);
+
+
if (rt_entry_relation->rd_rules != NULL)
{
result =
rt_entry_locks = rt_entry_relation->rd_rules;
heap_close(rt_entry_relation);
+
if (rt_entry_locks)
{
locks =
List *
QueryRewrite(Query *parsetree)
{
-
QueryRewriteSubLink(parsetree->qual);
return QueryRewriteOne(parsetree);
}
bool instead;
List *qual_products = NIL;
+
+
if (++numQueryRewriteInvoked > REWRITE_INVOKE_MAX)
{
elog(ERROR, "query rewritten %d times, may contain cycles",