From 4b05912f0b6aa69507bc32ac6ddaf8aeecdeb396 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Sun, 4 Jan 1998 04:31:43 +0000 Subject: [PATCH] Fix for count(*), aggs with views and multiple tables and sum(3). --- src/backend/executor/nodeAgg.c | 55 +++++++++++------- src/backend/nodes/copyfuncs.c | 3 +- src/backend/parser/gram.y | 11 ++-- src/backend/parser/parse_agg.c | 84 ++++++++++++++++++++++++---- src/backend/parser/parse_func.c | 14 ++--- src/backend/parser/parse_relation.c | 30 +--------- src/backend/parser/parse_target.c | 7 ++- src/backend/rewrite/locks.c | 28 ++++++++-- src/backend/rewrite/rewriteHandler.c | 3 +- src/backend/rewrite/rewriteManip.c | 45 ++++++++++++++- src/include/nodes/primnodes.h | 15 ++--- src/include/parser/parse_agg.h | 5 +- src/include/parser/parse_expr.h | 5 +- src/include/parser/parse_func.h | 4 +- src/include/parser/parse_relation.h | 3 +- 15 files changed, 215 insertions(+), 97 deletions(-) diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 59c18ab158..2037994027 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -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; } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 96dc5097e1..edc055dfdb 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -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); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index c64c8d41d2..963d5adf0d 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 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; diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index e776f69500..a244d0398c 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -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 $ * *------------------------------------------------------------------------- */ @@ -18,14 +18,17 @@ #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; } diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 4d1017b54a..43c78e299d 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -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)), diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 2b880213d7..e2c53ed152 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -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 diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 04739fe550..a7049b0b3f 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -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); diff --git a/src/backend/rewrite/locks.c b/src/backend/rewrite/locks.c index d446da653c..70dc37080e 100644 --- a/src/backend/rewrite/locks.c +++ b/src/backend/rewrite/locks.c @@ -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; + } /* diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index d6dc95e387..1f6bd86343 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.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); } } diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index f7e3896040..122067a242 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.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); } diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index f0706d1392..1e896e5e13 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -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; /* ---------------- diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h index 9761aa94e1..8d1e0fb31f 100644 --- a/src/include/parser/parse_agg.h +++ b/src/include/parser/parse_agg.h @@ -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 */ diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index f26bf34acb..ba8eed9c81 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -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 */ diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index 9ff6ee91b8..12d6ba16b8 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -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); diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index 7c78757ac3..e379b92932 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -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); -- 2.40.0