]> granicus.if.org Git - postgresql/commitdiff
Fix for count(*), aggs with views and multiple tables and sum(3).
authorBruce Momjian <bruce@momjian.us>
Sun, 4 Jan 1998 04:31:43 +0000 (04:31 +0000)
committerBruce Momjian <bruce@momjian.us>
Sun, 4 Jan 1998 04:31:43 +0000 (04:31 +0000)
15 files changed:
src/backend/executor/nodeAgg.c
src/backend/nodes/copyfuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_agg.c
src/backend/parser/parse_func.c
src/backend/parser/parse_relation.c
src/backend/parser/parse_target.c
src/backend/rewrite/locks.c
src/backend/rewrite/rewriteHandler.c
src/backend/rewrite/rewriteManip.c
src/include/nodes/primnodes.h
src/include/parser/parse_agg.h
src/include/parser/parse_expr.h
src/include/parser/parse_func.h
src/include/parser/parse_relation.h

index 59c18ab158c2d0490b73a8d36288d0ab3624c063..2037994027a800290e84284df5c65d5afaa39861 100644 (file)
@@ -278,7 +278,7 @@ ExecAgg(Agg *node)
                for (i = 0; i < nagg; i++)
                {
                        AttrNumber      attnum;
-                       int2            attlen;
+                       int2            attlen = 0;
                        Datum           newVal = (Datum) NULL;
                        AggFuncInfo *aggfns = &aggFuncInfo[i];
                        Datum           args[2];
@@ -298,18 +298,24 @@ ExecAgg(Agg *node)
                                        newVal = ExecEvalExpr(aggregates[i]->target, econtext,
                                                                                  &isNull, &isDone);
                                        break;
+                               case T_Const:
+                                       tagnode = NULL;
+                                       econtext->ecxt_scantuple = outerslot;
+                                       newVal = ExecEvalExpr(aggregates[i]->target, econtext,
+                                                                                 &isNull, &isDone);
+                                       break;
                                default:
                                        elog(WARN, "ExecAgg: Bad Agg->Target for Agg %d", i);
                        }
 
-                       if (isNull)
+                       if (isNull && !aggregates[i]->usenulls)
                                continue;               /* ignore this tuple for this agg */
 
                        if (aggfns->xfn1)
                        {
                                if (noInitValue[i])
                                {
-                                       int                     byVal;
+                                       int                     byVal = 0;
 
                                        /*
                                         * value1 and value2 has not been initialized. This is
@@ -322,22 +328,34 @@ ExecAgg(Agg *node)
                                         * a copy of it since the tuple from which it came
                                         * will be freed on the next iteration of the scan
                                         */
-                                       if (tagnode != NULL)
-                                       {
-                                               FunctionCachePtr fcache_ptr;
-
-                                               if (nodeTag(tagnode) == T_Func)
-                                                       fcache_ptr = ((Func *) tagnode)->func_fcache;
-                                               else
-                                                       fcache_ptr = ((Oper *) tagnode)->op_fcache;
-                                               attlen = fcache_ptr->typlen;
-                                               byVal = fcache_ptr->typbyval;
-                                       }
-                                       else
+                                       switch (nodeTag(aggregates[i]->target))
                                        {
-                                               attnum = ((Var *) aggregates[i]->target)->varattno;
-                                               attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
-                                               byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
+                                               case T_Var:
+                                                       attnum = ((Var *) aggregates[i]->target)->varattno;
+                                                       attlen = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attlen;
+                                                       byVal = outerslot->ttc_tupleDescriptor->attrs[attnum - 1]->attbyval;
+
+                                                       break;
+                                               case T_Expr:
+                                               {
+                                                       FunctionCachePtr fcache_ptr;
+               
+                                                       if (nodeTag(tagnode) == T_Func)
+                                                               fcache_ptr = ((Func *) tagnode)->func_fcache;
+                                                       else
+                                                               fcache_ptr = ((Oper *) tagnode)->op_fcache;
+                                                       attlen = fcache_ptr->typlen;
+                                                       byVal = fcache_ptr->typbyval;
+
+                                                       break;
+                                               }
+                                               case T_Const:
+                                                       attlen = ((Const *) aggregates[i]->target)->constlen;
+                                                       byVal = ((Const *) aggregates[i]->target)->constbyval;
+
+                                                       break;
+                                               default:
+                                                       elog(WARN, "ExecAgg: Bad Agg->Target for Agg %d", i);
                                        }
                                        if (attlen == -1)
                                        {
@@ -349,7 +367,6 @@ ExecAgg(Agg *node)
                                                value1[i] = newVal;
                                        else
                                                memmove((char *) (value1[i]), (char *) newVal, attlen);
-                                       /* value1[i] = newVal; */
                                        noInitValue[i] = 0;
                                        nulls[i] = 0;
                                }
index 96dc5097e1020dda46a6206800f6f3b0c5261ae5..edc055dfdb0d1770656f231458748d51fc447279 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.26 1997/12/24 06:05:52 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.27 1998/01/04 04:31:02 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -899,6 +899,7 @@ _copyAggreg(Aggreg *from)
        newnode->aggname = pstrdup(from->aggname);
        newnode->basetype = from->basetype;
        newnode->aggtype = from->aggtype;
+       newnode->usenulls = from->usenulls;
 
        Node_Copy(from, newnode, target);
 
index c64c8d41d25dfd2366973210c4fe6fc750ae1e5f..963d5adf0dc569798affb69d8b0fa2386cf45caf 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.82 1998/01/01 05:44:53 thomas Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.83 1998/01/04 04:31:08 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -2381,8 +2381,6 @@ OptUseOp:  USING Op                                                               { $$ = $2; }
  *
  *     ...however, recursive addattr and rename supported.  make special
  *     cases for these.
- *
- *     XXX i believe '*' should be the default behavior, but...
  */
 opt_inh_star:  '*'                                                             { $$ = TRUE; }
                | /*EMPTY*/                                                             { $$ = FALSE; }
@@ -2978,11 +2976,12 @@ a_expr:  attr opt_indirection
                                }
                | name '(' '*' ')'
                                {
+                                       /* cheap hack for aggregate (eg. count) */
                                        FuncCall *n = makeNode(FuncCall);
-                                       Ident *star = makeNode(Ident);
+                                       A_Const *star = makeNode(A_Const);
 
-                                       /* cheap hack for aggregate (eg. count) */
-                                       star->name = "oid";
+                                       star->val.type = T_String;
+                                       star->val.val.str = "";
                                        n->funcname = $1;
                                        n->args = lcons(star, NIL);
                                        $$ = (Node *)n;
index e776f695000bbd0bb808ef476a44907f6816b509..a244d0398ce54eb80f507b5238b5fd8f5ae90b26 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.4 1997/12/22 05:42:19 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.5 1998/01/04 04:31:14 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 #include "access/heapam.h"
 #include "catalog/pg_aggregate.h"
+#include "catalog/pg_type.h"
 #include "nodes/nodeFuncs.h"
 #include "nodes/primnodes.h"
 #include "nodes/relation.h"
 #include "optimizer/clauses.h"
 #include "parser/parse_agg.h"
+#include "parser/parse_expr.h"
 #include "parser/parse_node.h"
 #include "parser/parse_target.h"
 #include "utils/syscache.h"
+#include "utils/lsyscache.h"
 
 static bool contain_agg_clause(Node *clause);
 static bool exprIsAggOrGroupCol(Node *expr, List *groupClause);
@@ -276,7 +279,8 @@ parseCheckAggregates(ParseState *pstate, Query *qry)
 
 
 Aggreg    *
-ParseAgg(char *aggname, Oid basetype, Node *target)
+ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
+                       List *target, int precedence)
 {
        Oid                     fintype;
        Oid                     vartype;
@@ -284,7 +288,8 @@ ParseAgg(char *aggname, Oid basetype, Node *target)
        Form_pg_aggregate aggform;
        Aggreg     *aggreg;
        HeapTuple       theAggTuple;
-
+       bool            usenulls = false;
+       
        theAggTuple = SearchSysCacheTuple(AGGNAME, PointerGetDatum(aggname),
                                                                          ObjectIdGetDatum(basetype),
                                                                          0, 0);
@@ -293,21 +298,78 @@ ParseAgg(char *aggname, Oid basetype, Node *target)
                elog(WARN, "aggregate %s does not exist", aggname);
        }
 
+       /*
+        *      We do a major hack for count(*) here.
+        *
+        *      Count(*) poses several problems.  First, we need a field that is
+        *      guaranteed to be in the range table, and unique.  Using a constant
+        *      causes the optimizer to properly remove the aggragate from any
+        *      elements of the query.
+        *      Using just 'oid', which can not be null, in the parser fails on:
+        *
+        *              select count(*) from tab1, tab2     -- oid is not unique
+        *              select count(*) from viewtable          -- views don't have real oids
+        *
+        *      So, for an aggregate with parameter '*', we use the first valid
+        *      range table entry, and pick the first column from the table.
+        *      We set a flag to count nulls, because we could have nulls in
+        *      that column.
+       */
+               
+       if (nodeTag(lfirst(target)) == T_Const)
+       {
+               Const *con = (Const *)lfirst(target);
+               
+               if (con->consttype == UNKNOWNOID && VARSIZE(con->constvalue) == VARHDRSZ)
+               {
+                       Attr *attr = makeNode(Attr);
+                       List       *rtable, *rlist;
+                       RangeTblEntry *first_valid_rte;
+
+                       Assert(lnext(target) == NULL);
+
+                       if (pstate->p_is_rule)
+                               rtable = lnext(lnext(pstate->p_rtable));
+                       else
+                               rtable = pstate->p_rtable;
+               
+                       first_valid_rte = NULL;
+                       foreach(rlist, rtable)
+                       {
+                               RangeTblEntry *rte = lfirst(rlist);
+               
+                               /* only entries on outer(non-function?) scope */
+                               if (!rte->inFromCl && rte != pstate->p_target_rangetblentry)
+                                       continue;
+
+                               first_valid_rte =rte;
+                               break;
+                       }
+                       if (first_valid_rte == NULL)
+                               elog(WARN, "Can't find column to do aggregate(*) on.");
+                               
+                       attr->relname = first_valid_rte->refname;
+                       attr->attrs = lcons(makeString(
+                                                       get_attname(first_valid_rte->relid,1)),NIL);
+
+                       lfirst(target) = transformExpr(pstate, (Node *) attr, precedence);
+                       usenulls = true;
+               }
+       }
+       
        aggform = (Form_pg_aggregate) GETSTRUCT(theAggTuple);
        fintype = aggform->aggfinaltype;
        xfn1 = aggform->aggtransfn1;
 
-       if (nodeTag(target) != T_Var && nodeTag(target) != T_Expr)
-               elog(WARN, "parser: aggregate can only be applied on an attribute or expression");
-
+       
        /* only aggregates with transfn1 need a base type */
        if (OidIsValid(xfn1))
        {
                basetype = aggform->aggbasetype;
-               if (nodeTag(target) == T_Var)
-                       vartype = ((Var *) target)->vartype;
+               if (nodeTag(lfirst(target)) == T_Var)
+                       vartype = ((Var *) lfirst(target))->vartype;
                else
-                       vartype = ((Expr *) target)->typeOid;
+                       vartype = ((Expr *) lfirst(target))->typeOid;
 
                if (basetype != vartype)
                {
@@ -327,7 +389,9 @@ ParseAgg(char *aggname, Oid basetype, Node *target)
        aggreg->basetype = aggform->aggbasetype;
        aggreg->aggtype = fintype;
 
-       aggreg->target = target;
+       aggreg->target = lfirst(target);
+       if (usenulls)
+               aggreg->usenulls = true;
 
        return aggreg;
 }
index 4d1017b54a0735e22bdbc231f2e84a1b0eff7176..43c78e299de626cd854fb8ccc927c4c7a648de0d 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.3 1997/11/26 03:42:42 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.4 1998/01/04 04:31:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -87,7 +87,8 @@ typedef struct _SuperQE
  */
 
 Node *
-ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
+ParseFunc(ParseState *pstate, char *funcname, List *fargs,
+               int *curr_resno, int precedence)
 {
        Oid                     rettype = (Oid) 0;
        Oid                     argrelid = (Oid) 0;
@@ -194,9 +195,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
                                 */
                                if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
                                        && strcmp(funcname, "*"))
-                               {
                                        elog(WARN, "Functions on sets are not yet supported");
-                               }
                        }
 
                        if (retval)
@@ -223,7 +222,8 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
                                                                        ObjectIdGetDatum(basetype),
                                                                        0, 0))
                        {
-                               Aggreg     *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
+                               Aggreg     *aggreg = ParseAgg(pstate, funcname, basetype,
+                                                                               fargs, precedence);
 
                                AddAggToParseState(pstate, aggreg);
                                return (Node *) aggreg;
@@ -368,7 +368,7 @@ ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
                else
                {
                        funcnode->func_tlist = setup_tlist(funcname, argrelid);
-                       rettype = attnameTypeId(argrelid, funcname);
+                       rettype = get_atttype(argrelid, get_attnum(argrelid, funcname));
                }
        }
 
@@ -1031,7 +1031,7 @@ setup_tlist(char *attname, Oid relid)
        if (attno < 0)
                elog(WARN, "cannot reference attribute '%s' of tuple params/return values for functions", attname);
 
-       typeid = attnameTypeId(relid, attname);
+       typeid = get_atttype(relid, attno);
        resnode = makeResdom(1,
                                                 typeid,
                                                 typeLen(typeidType(typeid)),
index 2b880213d7d4a9f908b93080f9230bc42810a4d4..e2c53ed15230abf98c6187940a54ca3e919d2ee3 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.3 1997/11/26 03:42:48 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.4 1998/01/04 04:31:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -346,34 +346,6 @@ attnumAttNelems(Relation rd, int attid)
        return (rd->rd_att->attrs[attid - 1]->attnelems);
 }
 
-Oid
-attnameTypeId(Oid relid, char *attrname)
-{
-       int                     attid;
-       Oid                     vartype;
-       Relation        rd;
-
-       rd = heap_open(relid);
-       if (!RelationIsValid(rd))
-       {
-               rd = heap_openr(typeidTypeName(relid));
-               if (!RelationIsValid(rd))
-                       elog(WARN, "cannot compute type of att %s for relid %d",
-                                attrname, relid);
-       }
-
-       attid = attnameAttNum(rd, attrname); /* could elog(WARN) and never return */
-
-       vartype = attnumTypeId(rd, attid);
-
-       /*
-        * close relation we're done with it now
-        */
-       heap_close(rd);
-
-       return (vartype);
-}
-
 /* given attribute id, return type of that attribute */
 /* XXX Special case for pseudo-attributes is a hack */
 Oid
index 04739fe5503593bf7b5136d8a916713b6569682f..a7049b0b3f73f2a0d1ba8f410e5d42b2239a68f7 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.3 1997/11/26 03:42:49 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.4 1998/01/04 04:31:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -255,7 +255,7 @@ transformTargetList(ParseState *pstate, List *targetlist)
                                         * Target item is fully specified: ie.
                                         * relation.attribute
                                         */
-                                       result = handleNestedDots(pstate, att, &pstate->p_last_resno);
+                                       result = handleNestedDots(pstate, att, &pstate->p_last_resno,EXPR_COLUMN_FIRST);
                                        handleTargetColname(pstate, &res->name, att->relname, attrname);
                                        if (att->indirection != NIL)
                                        {
@@ -467,7 +467,8 @@ make_targetlist_expr(ParseState *pstate,
                        att->relname = pstrdup(RelationGetRelationName(rd)->data);
                        att->attrs = lcons(makeString(colname), NIL);
                        target_expr = (Expr *) handleNestedDots(pstate, att,
-                                                                                                 &pstate->p_last_resno);
+                                                                                                 &pstate->p_last_resno,
+                                                                                                 EXPR_COLUMN_FIRST);
                        while (ar != NIL)
                        {
                                A_Indices  *ind = lfirst(ar);
index d446da653cc3672075c9d483f76b4bf0d7607c92..70dc37080e2a5d098accbc08d17d3d5d7fdec8c9 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.5 1997/09/08 21:46:33 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/Attic/locks.c,v 1.6 1998/01/04 04:31:27 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -58,6 +58,14 @@ nodeThisLockWasTriggered(Node *node, int varno, AttrNumber attnum)
                                        nodeThisLockWasTriggered(tle->expr, varno, attnum);
                        }
                        break;
+               case T_Aggreg:
+                       {
+                               Aggreg *agg = (Aggreg *) node;
+
+                               return
+                                       nodeThisLockWasTriggered(agg->target, varno, attnum);
+                       }
+                       break;
                case T_List:
                        {
                                List       *l;
@@ -87,10 +95,20 @@ thisLockWasTriggered(int varno,
                                         AttrNumber attnum,
                                         Query *parsetree)
 {
-       return
-       (nodeThisLockWasTriggered(parsetree->qual, varno, attnum) ||
-        nodeThisLockWasTriggered((Node *) parsetree->targetList,
-                                                         varno, attnum));
+       int i;
+       
+       if (nodeThisLockWasTriggered(parsetree->qual, varno, attnum))
+               return true;
+
+       if (nodeThisLockWasTriggered((Node *) parsetree->targetList, varno, attnum))
+               return true;
+
+       for(i=0; i < parsetree->qry_numAgg; i++)
+               if (nodeThisLockWasTriggered(parsetree->qry_aggs[i]->target,
+                                       varno, attnum))
+                       return true;
+       return false;
+               
 }
 
 /*
index d6dc95e387d7c0f39513065ead9e7599002b35db..1f6bd86343cc9c57835cee1b301c5d912fda15b6 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.6 1997/09/08 21:46:38 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.7 1998/01/04 04:31:28 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -225,6 +225,7 @@ FireRetrieveRulesAtQuery(Query *parsetree,
                        {
                                *instead_flag = TRUE;
                                FixResdomTypes(parsetree->targetList);
+
                                return lcons(parsetree, NIL);
                        }
                }
index f7e3896040c2ba9bb04f8efbb15eb662bb6c5888..122067a2424feb91ef9ca3a877656131b869cfce 100644 (file)
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.8 1997/09/18 20:21:11 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.9 1998/01/04 04:31:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -46,6 +46,13 @@ OffsetVarNodes(Node *node, int offset)
                                OffsetVarNodes(tle->expr, offset);
                        }
                        break;
+               case T_Aggreg:
+                       {
+                               Aggreg *agg = (Aggreg *) node;
+
+                               OffsetVarNodes(agg->target, offset);
+                       }
+                       break;
                case T_Expr:
                        {
                                Expr       *expr = (Expr *) node;
@@ -91,6 +98,13 @@ ChangeVarNodes(Node *node, int old_varno, int new_varno)
                                ChangeVarNodes(tle->expr, old_varno, new_varno);
                        }
                        break;
+               case T_Aggreg:
+                       {
+                               Aggreg *agg = (Aggreg *) node;
+
+                               ChangeVarNodes(agg->target, old_varno, new_varno);
+                       }
+                       break;
                case T_Expr:
                        {
                                Expr       *expr = (Expr *) node;
@@ -235,6 +249,9 @@ ResolveNew(RewriteInfo *info, List *targetlist, Node **nodePtr)
                case T_TargetEntry:
                        ResolveNew(info, targetlist, &((TargetEntry *) node)->expr);
                        break;
+               case T_Aggreg:
+                       ResolveNew(info, targetlist, &((Aggreg *) node)->target);
+                       break;
                case T_Expr:
                        ResolveNew(info, targetlist, (Node **) (&(((Expr *) node)->args)));
                        break;
@@ -325,6 +342,14 @@ nodeHandleRIRAttributeRule(Node **nodePtr,
                                                                   rt_index, attr_num, modified, badsql);
                        }
                        break;
+               case T_Aggreg:
+                       {
+                               Aggreg *agg = (Aggreg *) node;
+
+                               nodeHandleRIRAttributeRule(&agg->target, rtable, targetlist,
+                                                                  rt_index, attr_num, modified, badsql);
+                       }
+                       break;
                case T_Expr:
                        {
                                Expr       *expr = (Expr *) node;
@@ -395,11 +420,16 @@ HandleRIRAttributeRule(Query *parsetree,
                                           int *modified,
                                           int *badsql)
 {
+       int i;
+       
        nodeHandleRIRAttributeRule((Node **) (&(parsetree->targetList)), rtable,
                                                           targetlist, rt_index, attr_num,
                                                           modified, badsql);
        nodeHandleRIRAttributeRule(&parsetree->qual, rtable, targetlist,
                                                           rt_index, attr_num, modified, badsql);
+       for(i=0; i < parsetree->qry_numAgg; i++)
+               nodeHandleRIRAttributeRule(&parsetree->qry_aggs[i]->target, rtable,
+                                       targetlist, rt_index, attr_num, modified, badsql);
 }
 
 
@@ -437,6 +467,14 @@ nodeHandleViewRule(Node **nodePtr,
                                                                   rt_index, modified);
                        }
                        break;
+               case T_Aggreg:
+                       {
+                               Aggreg *agg = (Aggreg *) node;
+
+                               nodeHandleViewRule(&(agg->target), rtable, targetlist,
+                                                                  rt_index, modified);
+                       }
+                       break;
                case T_Expr:
                        {
                                Expr       *expr = (Expr *) node;
@@ -483,8 +521,13 @@ HandleViewRule(Query *parsetree,
                           int rt_index,
                           int *modified)
 {
+       int i;
+       
        nodeHandleViewRule(&parsetree->qual, rtable, targetlist, rt_index,
                                           modified);
        nodeHandleViewRule((Node **) (&(parsetree->targetList)), rtable, targetlist,
                                           rt_index, modified);
+       for(i=0; i < parsetree->qry_numAgg; i++)
+               nodeHandleViewRule(&parsetree->qry_aggs[i]->target, rtable, targetlist, rt_index,
+                                          modified);
 }
index f0706d1392e04c6699d48985d91c1172cb8efed5..1e896e5e1365fe7b3dc06d49225b97c18dbce922 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: primnodes.h,v 1.11 1997/09/08 21:52:58 momjian Exp $
+ * $Id: primnodes.h,v 1.12 1998/01/04 04:31:37 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -255,18 +255,19 @@ typedef struct Func
  *             aggname                 - name of the aggregate
  *             basetype                - base type Oid of the aggregate
  *             aggtype                 - type Oid of final result of the aggregate
- *             query                   - XXX comment me
- *             target                  - XXX comment me
+ *             target                  - attribute or expression we are aggregating on
+ *             aggno                   - index to ecxt_values
  * ----------------
  */
 typedef struct Aggreg
 {
        NodeTag         type;
        char       *aggname;
-       Oid                     basetype;               /* base type of the aggregate */
-       Oid                     aggtype;                /* type of final result */
-       Node       *target;                     /* attribute to aggreg on */
-       int                     aggno;                  /* index to ecxt_values */
+       Oid                     basetype;
+       Oid                     aggtype;
+       Node       *target;     
+       int                     aggno;
+       bool            usenulls;
 } Aggreg;
 
 /* ----------------
index 9761aa94e17ed46485540c53161cb036a03f856d..8d1e0fb31fd426731430b8b6765a3df5f93c38f8 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_agg.h,v 1.3 1997/11/26 03:43:08 momjian Exp $
+ * $Id: parse_agg.h,v 1.4 1998/01/04 04:31:39 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,7 +21,8 @@
 extern void AddAggToParseState(ParseState *pstate, Aggreg *aggreg);
 extern void finalizeAggregates(ParseState *pstate, Query *qry);
 extern void parseCheckAggregates(ParseState *pstate, Query *qry);
-extern Aggreg *ParseAgg(char *aggname, Oid basetype, Node *target);
+extern Aggreg *ParseAgg(ParseState *pstate, char *aggname, Oid basetype,
+                       List *target, int precedence);
 extern void agg_error(char *caller, char *aggname, Oid basetypeID);
 
 #endif                                                 /* PARSE_AGG_H */
index f26bf34acb994bbd85c756ffe519ed0d53ade68f..ba8eed9c814b7d33ec4106e184f5349c52d92106 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_expr.h,v 1.3 1997/11/26 03:43:11 momjian Exp $
+ * $Id: parse_expr.h,v 1.4 1998/01/04 04:31:41 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,7 +21,8 @@
 extern Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
 extern Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
 extern Oid exprType(Node *expr);
-extern Node *handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno);
+extern Node *handleNestedDots(ParseState *pstate, Attr *attr,
+               int *curr_resno, int precedence);
 extern Node *parser_typecast2(Node *expr, Oid exprType, Type tp, int typlen);
 
 #endif                                                 /* PARSE_EXPR_H */
index 9ff6ee91b80579bca8b52037bc11c634400111ad..12d6ba16b88c097c02d0434d64a6279822a3592b 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_func.h,v 1.3 1997/11/26 03:43:12 momjian Exp $
+ * $Id: parse_func.h,v 1.4 1998/01/04 04:31:42 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -43,7 +43,7 @@ typedef struct _CandidateList
 }                 *CandidateList;
 
 extern Node *ParseFunc(ParseState *pstate, char *funcname, List *fargs,
-       int *curr_resno);
+       int *curr_resno, int precedence);
 
 extern void func_error(char *caller, char *funcname, int nargs, Oid *argtypes);
 
index 7c78757ac32e55003edcef50f40c7d98fea6509a..e379b92932f5fd9e6f746ba0585a285140b5656e 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_relation.h,v 1.3 1997/11/26 03:43:16 momjian Exp $
+ * $Id: parse_relation.h,v 1.4 1998/01/04 04:31:43 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -34,7 +34,6 @@ extern int attnameAttNum(Relation rd, char *a);
 extern bool attnameIsSet(Relation rd, char *name);
 extern char *attnumAttName(Relation rd, int attrno);
 extern int attnumAttNelems(Relation rd, int attid);
-extern Oid attnameTypeId(Oid relid, char *attrname);
 extern Oid attnumTypeId(Relation rd, int attid);
 extern void handleTargetColname(ParseState *pstate, char **resname,
                                        char *refname, char *colname);