1 /*-------------------------------------------------------------------------
4 * transform the parse tree into a query tree
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.39 1997/09/07 04:44:38 momjian Exp $
12 *-------------------------------------------------------------------------
18 #include "nodes/nodes.h"
19 #include "nodes/params.h"
20 #include "nodes/primnodes.h"
21 #include "nodes/parsenodes.h"
22 #include "nodes/relation.h"
23 #include "parse.h" /* for AND, OR, etc. */
24 #include "catalog/pg_type.h" /* for INT4OID, etc. */
25 #include "catalog/pg_proc.h"
26 #include "utils/elog.h"
27 #include "utils/builtins.h" /* namecmp(), textout() */
28 #include "utils/lsyscache.h"
29 #include "utils/palloc.h"
30 #include "utils/mcxt.h"
31 #include "utils/syscache.h"
32 #include "utils/acl.h"
33 #include "parser/parse_query.h"
34 #include "parser/parse_state.h"
35 #include "nodes/makefuncs.h" /* for makeResdom(), etc. */
36 #include "nodes/nodeFuncs.h"
37 #include "commands/sequence.h"
39 #include "optimizer/clauses.h"
40 #include "access/heapam.h"
42 #include "miscadmin.h"
44 #include "port-protos.h" /* strdup() */
46 /* convert the parse tree into a query tree */
47 static Query *transformStmt(ParseState * pstate, Node * stmt);
49 static Query *transformDeleteStmt(ParseState * pstate, DeleteStmt * stmt);
50 static Query *transformInsertStmt(ParseState * pstate, AppendStmt * stmt);
51 static Query *transformIndexStmt(ParseState * pstate, IndexStmt * stmt);
52 static Query *transformExtendStmt(ParseState * pstate, ExtendStmt * stmt);
53 static Query *transformRuleStmt(ParseState * query, RuleStmt * stmt);
54 static Query *transformSelectStmt(ParseState * pstate, RetrieveStmt * stmt);
55 static Query *transformUpdateStmt(ParseState * pstate, ReplaceStmt * stmt);
56 static Query *transformCursorStmt(ParseState * pstate, CursorStmt * stmt);
57 static Node *handleNestedDots(ParseState * pstate, Attr * attr, int *curr_resno);
59 #define EXPR_COLUMN_FIRST 1
60 #define EXPR_RELATION_FIRST 2
61 static Node *transformExpr(ParseState * pstate, Node * expr, int precedence);
62 static Node *transformIdent(ParseState * pstate, Node * expr, int precedence);
64 static void makeRangeTable(ParseState * pstate, char *relname, List * frmList);
65 static List *expandAllTables(ParseState * pstate);
66 static char *figureColname(Node * expr, Node * resval);
67 static List *makeTargetNames(ParseState * pstate, List * cols);
68 static List *transformTargetList(ParseState * pstate, List * targetlist);
70 make_targetlist_expr(ParseState * pstate,
71 char *colname, Node * expr,
73 static bool inWhereClause = false;
74 static Node *transformWhereClause(ParseState * pstate, Node * a_expr);
76 transformGroupClause(ParseState * pstate, List * grouplist,
79 transformSortClause(ParseState * pstate,
80 List * orderlist, List * targetlist,
83 static void parseFromClause(ParseState * pstate, List * frmList);
85 ParseFunc(ParseState * pstate, char *funcname,
86 List * fargs, int *curr_resno);
87 static List *setup_tlist(char *attname, Oid relid);
88 static List *setup_base_tlist(Oid typeid);
90 make_arguments(int nargs, List * fargs, Oid * input_typeids,
91 Oid * function_typeids);
92 static void AddAggToParseState(ParseState * pstate, Aggreg * aggreg);
93 static void finalizeAggregates(ParseState * pstate, Query * qry);
94 static void parseCheckAggregates(ParseState * pstate, Query * qry);
95 static ParseState *makeParseState(void);
97 /*****************************************************************************
99 *****************************************************************************/
102 * makeParseState() --
103 * allocate and initialize a new ParseState.
104 * the CALLERS is responsible for freeing the ParseState* returned
113 pstate = malloc(sizeof(ParseState));
114 pstate->p_last_resno = 1;
115 pstate->p_rtable = NIL;
116 pstate->p_numAgg = 0;
117 pstate->p_aggs = NIL;
118 pstate->p_is_insert = false;
119 pstate->p_insert_columns = NIL;
120 pstate->p_is_update = false;
121 pstate->p_is_rule = false;
122 pstate->p_target_relation = NULL;
123 pstate->p_target_rangetblentry = NULL;
130 * analyze a list of parse trees and transform them if necessary.
132 * Returns a list of transformed parse trees. Optimizable statements are
133 * all transformed to Query while the rest stays the same.
135 * CALLER is responsible for freeing the QueryTreeList* returned
138 parse_analyze(List * pl)
140 QueryTreeList *result;
144 result = malloc(sizeof(QueryTreeList));
145 result->len = length(pl);
146 result->qtrees = (Query **) malloc(result->len * sizeof(Query *));
148 inWhereClause = false; /* to avoid nextval(sequence) in WHERE */
152 pstate = makeParseState();
153 result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
155 if (pstate->p_target_relation != NULL)
156 heap_close(pstate->p_target_relation);
165 * transform a Parse tree. If it is an optimizable statement, turn it
169 transformStmt(ParseState * pstate, Node * parseTree)
171 Query *result = NULL;
173 switch (nodeTag(parseTree))
175 /*------------------------
176 * Non-optimizable statements
177 *------------------------
180 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
184 result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
188 result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
193 ViewStmt *n = (ViewStmt *) parseTree;
195 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
196 result = makeNode(Query);
197 result->commandType = CMD_UTILITY;
198 result->utilityStmt = (Node *) n;
204 MemoryContext oldcontext;
207 * make sure that this Query is allocated in TopMemory context
208 * because vacuum spans transactions and we don't want to lose
209 * the vacuum Query due to end-of-transaction free'ing
211 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
212 result = makeNode(Query);
213 result->commandType = CMD_UTILITY;
214 result->utilityStmt = (Node *) parseTree;
215 MemoryContextSwitchTo(oldcontext);
221 ExplainStmt *n = (ExplainStmt *) parseTree;
223 result = makeNode(Query);
224 result->commandType = CMD_UTILITY;
225 n->query = transformStmt(pstate, (Node *) n->query);
226 result->utilityStmt = (Node *) parseTree;
230 /*------------------------
231 * Optimizable statements
232 *------------------------
235 result = transformInsertStmt(pstate, (AppendStmt *) parseTree);
239 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
243 result = transformUpdateStmt(pstate, (ReplaceStmt *) parseTree);
247 result = transformCursorStmt(pstate, (CursorStmt *) parseTree);
251 result = transformSelectStmt(pstate, (RetrieveStmt *) parseTree);
257 * other statments don't require any transformation-- just return
258 * the original parsetree
260 result = makeNode(Query);
261 result->commandType = CMD_UTILITY;
262 result->utilityStmt = (Node *) parseTree;
269 * transformDeleteStmt -
270 * transforms a Delete Statement
273 transformDeleteStmt(ParseState * pstate, DeleteStmt * stmt)
275 Query *qry = makeNode(Query);
277 qry->commandType = CMD_DELETE;
279 /* set up a range table */
280 makeRangeTable(pstate, stmt->relname, NULL);
282 qry->uniqueFlag = NULL;
284 /* fix where clause */
285 qry->qual = transformWhereClause(pstate, stmt->whereClause);
287 qry->rtable = pstate->p_rtable;
288 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
290 /* make sure we don't have aggregates in the where clause */
291 if (pstate->p_numAgg > 0)
292 parseCheckAggregates(pstate, qry);
294 return (Query *) qry;
298 * transformInsertStmt -
299 * transform an Insert Statement
302 transformInsertStmt(ParseState * pstate, AppendStmt * stmt)
304 Query *qry = makeNode(Query); /* make a new query tree */
306 qry->commandType = CMD_INSERT;
307 pstate->p_is_insert = true;
309 /* set up a range table */
310 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
312 qry->uniqueFlag = NULL;
314 /* fix the target list */
315 pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
317 qry->targetList = transformTargetList(pstate, stmt->targetList);
319 /* fix where clause */
320 qry->qual = transformWhereClause(pstate, stmt->whereClause);
322 /* now the range table will not change */
323 qry->rtable = pstate->p_rtable;
324 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
326 if (pstate->p_numAgg > 0)
327 finalizeAggregates(pstate, qry);
329 return (Query *) qry;
333 * transformIndexStmt -
334 * transforms the qualification of the index statement
337 transformIndexStmt(ParseState * pstate, IndexStmt * stmt)
342 q->commandType = CMD_UTILITY;
344 /* take care of the where clause */
345 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
346 stmt->rangetable = pstate->p_rtable;
348 q->utilityStmt = (Node *) stmt;
354 * transformExtendStmt -
355 * transform the qualifications of the Extend Index Statement
359 transformExtendStmt(ParseState * pstate, ExtendStmt * stmt)
364 q->commandType = CMD_UTILITY;
366 /* take care of the where clause */
367 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
368 stmt->rangetable = pstate->p_rtable;
370 q->utilityStmt = (Node *) stmt;
375 * transformRuleStmt -
376 * transform a Create Rule Statement. The actions is a list of parse
377 * trees which is transformed into a list of query trees.
380 transformRuleStmt(ParseState * pstate, RuleStmt * stmt)
386 q->commandType = CMD_UTILITY;
388 actions = stmt->actions;
391 * transform each statment, like parse_analyze()
393 while (actions != NIL)
397 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
400 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
402 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
405 pstate->p_last_resno = 1;
406 pstate->p_is_rule = true; /* for expand all */
407 pstate->p_numAgg = 0;
408 pstate->p_aggs = NULL;
410 lfirst(actions) = transformStmt(pstate, lfirst(actions));
411 actions = lnext(actions);
414 /* take care of the where clause */
415 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
417 q->utilityStmt = (Node *) stmt;
423 * transformSelectStmt -
424 * transforms a Select Statement
428 transformSelectStmt(ParseState * pstate, RetrieveStmt * stmt)
430 Query *qry = makeNode(Query);
432 qry->commandType = CMD_SELECT;
434 /* set up a range table */
435 makeRangeTable(pstate, NULL, stmt->fromClause);
437 qry->uniqueFlag = stmt->unique;
439 qry->into = stmt->into;
440 qry->isPortal = FALSE;
442 /* fix the target list */
443 qry->targetList = transformTargetList(pstate, stmt->targetList);
445 /* fix where clause */
446 qry->qual = transformWhereClause(pstate, stmt->whereClause);
448 /* check subselect clause */
449 if (stmt->selectClause)
450 elog(NOTICE, "UNION not yet supported; using first SELECT only", NULL);
452 /* check subselect clause */
453 if (stmt->havingClause)
454 elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
456 /* fix order clause */
457 qry->sortClause = transformSortClause(pstate,
462 /* fix group by clause */
463 qry->groupClause = transformGroupClause(pstate,
466 qry->rtable = pstate->p_rtable;
468 if (pstate->p_numAgg > 0)
469 finalizeAggregates(pstate, qry);
471 return (Query *) qry;
475 * transformUpdateStmt -
476 * transforms an update statement
480 transformUpdateStmt(ParseState * pstate, ReplaceStmt * stmt)
482 Query *qry = makeNode(Query);
484 qry->commandType = CMD_UPDATE;
485 pstate->p_is_update = true;
488 * the FROM clause is non-standard SQL syntax. We used to be able to
489 * do this with REPLACE in POSTQUEL so we keep the feature.
491 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
493 /* fix the target list */
494 qry->targetList = transformTargetList(pstate, stmt->targetList);
496 /* fix where clause */
497 qry->qual = transformWhereClause(pstate, stmt->whereClause);
499 qry->rtable = pstate->p_rtable;
500 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
502 /* make sure we don't have aggregates in the where clause */
503 if (pstate->p_numAgg > 0)
504 parseCheckAggregates(pstate, qry);
506 return (Query *) qry;
510 * transformCursorStmt -
511 * transform a Create Cursor Statement
515 transformCursorStmt(ParseState * pstate, CursorStmt * stmt)
517 Query *qry = makeNode(Query);
520 * in the old days, a cursor statement is a 'retrieve into portal'; If
521 * you change the following, make sure you also go through the code in
522 * various places that tests the kind of operation.
524 qry->commandType = CMD_SELECT;
526 /* set up a range table */
527 makeRangeTable(pstate, NULL, stmt->fromClause);
529 qry->uniqueFlag = stmt->unique;
531 qry->into = stmt->portalname;
532 qry->isPortal = TRUE;
533 qry->isBinary = stmt->binary; /* internal portal */
535 /* fix the target list */
536 qry->targetList = transformTargetList(pstate, stmt->targetList);
538 /* fix where clause */
539 qry->qual = transformWhereClause(pstate, stmt->whereClause);
541 /* fix order clause */
542 qry->sortClause = transformSortClause(pstate,
546 /* fix group by clause */
547 qry->groupClause = transformGroupClause(pstate,
551 qry->rtable = pstate->p_rtable;
553 if (pstate->p_numAgg > 0)
554 finalizeAggregates(pstate, qry);
556 return (Query *) qry;
559 /*****************************************************************************
561 * Transform Exprs, Aggs, etc.
563 *****************************************************************************/
567 * analyze and transform expressions. Type checking and type casting is
568 * done here. The optimizer and the executor cannot handle the original
569 * (raw) expressions collected by the parse tree. Hence the transformation
573 transformExpr(ParseState * pstate, Node * expr, int precedence)
580 switch (nodeTag(expr))
584 Attr *att = (Attr *) expr;
587 /* what if att.attrs == "*"?? */
588 temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
589 if (att->indirection != NIL)
591 List *idx = att->indirection;
595 A_Indices *ai = (A_Indices *) lfirst(idx);
599 uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
600 if (exprType(uexpr) != INT4OID)
601 elog(WARN, "array index expressions must be int4's");
602 if (ai->lidx != NULL)
604 lexpr = transformExpr(pstate, ai->lidx, precedence);
605 if (exprType(lexpr) != INT4OID)
606 elog(WARN, "array index expressions must be int4's");
610 if (ai->lidx != NULL)
617 * note we reuse the list of indices, make sure we
618 * don't free them! Otherwise, make a new list here
622 result = (Node *) make_array_ref(temp, att->indirection);
632 A_Const *con = (A_Const *) expr;
633 Value *val = &con->val;
635 if (con->typename != NULL)
637 result = parser_typecast(val, con->typename, -1);
641 result = (Node *) make_const(val);
647 ParamNo *pno = (ParamNo *) expr;
652 paramno = pno->number;
653 toid = param_type(paramno);
654 if (!OidIsValid(toid))
656 elog(WARN, "Parameter '$%d' is out of range",
659 param = makeNode(Param);
660 param->paramkind = PARAM_NUM;
661 param->paramid = (AttrNumber) paramno;
662 param->paramname = "<unnamed>";
663 param->paramtype = (Oid) toid;
664 param->param_tlist = (List *) NULL;
666 result = (Node *) param;
671 A_Expr *a = (A_Expr *) expr;
677 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
678 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
680 result = (Node *) make_op(a->opname, lexpr, rexpr);
685 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
687 result = ParseFunc(pstate,
688 "nullvalue", lcons(lexpr, NIL),
689 &pstate->p_last_resno);
694 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
696 result = ParseFunc(pstate,
697 "nonnullvalue", lcons(lexpr, NIL),
698 &pstate->p_last_resno);
703 Expr *expr = makeNode(Expr);
704 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
705 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
707 if (exprType(lexpr) != BOOLOID)
709 "left-hand side of AND is type '%s', not bool",
710 tname(get_id_type(exprType(lexpr))));
711 if (exprType(rexpr) != BOOLOID)
713 "right-hand side of AND is type '%s', not bool",
714 tname(get_id_type(exprType(rexpr))));
715 expr->typeOid = BOOLOID;
716 expr->opType = AND_EXPR;
717 expr->args = makeList(lexpr, rexpr, -1);
718 result = (Node *) expr;
723 Expr *expr = makeNode(Expr);
724 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
725 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
727 if (exprType(lexpr) != BOOLOID)
729 "left-hand side of OR is type '%s', not bool",
730 tname(get_id_type(exprType(lexpr))));
731 if (exprType(rexpr) != BOOLOID)
733 "right-hand side of OR is type '%s', not bool",
734 tname(get_id_type(exprType(rexpr))));
735 expr->typeOid = BOOLOID;
736 expr->opType = OR_EXPR;
737 expr->args = makeList(lexpr, rexpr, -1);
738 result = (Node *) expr;
743 Expr *expr = makeNode(Expr);
744 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
746 if (exprType(rexpr) != BOOLOID)
748 "argument to NOT is type '%s', not bool",
749 tname(get_id_type(exprType(rexpr))));
750 expr->typeOid = BOOLOID;
751 expr->opType = NOT_EXPR;
752 expr->args = makeList(rexpr, -1);
753 result = (Node *) expr;
763 * look for a column name or a relation name (the default
766 result = transformIdent(pstate, expr, precedence);
771 FuncCall *fn = (FuncCall *) expr;
774 /* transform the list of arguments */
775 foreach(args, fn->args)
776 lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
777 result = ParseFunc(pstate,
778 fn->funcname, fn->args, &pstate->p_last_resno);
782 /* should not reach here */
783 elog(WARN, "transformExpr: does not know how to transform %d\n",
792 transformIdent(ParseState * pstate, Node * expr, int precedence)
794 Ident *ident = (Ident *) expr;
800 column_result = relation_result = result = 0;
801 /* try to find the ident as a column */
802 if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
804 Attr *att = makeNode(Attr);
806 att->relname = rte->refname;
807 att->attrs = lcons(makeString(ident->name), NIL);
809 (Node *) handleNestedDots(pstate, att, &pstate->p_last_resno);
812 /* try to find the ident as a relation */
813 if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL)
816 relation_result = (Node *) ident;
819 /* choose the right result based on the precedence */
820 if (precedence == EXPR_COLUMN_FIRST)
823 result = column_result;
825 result = relation_result;
830 result = relation_result;
832 result = column_result;
836 elog(WARN, "attribute \"%s\" not found", ident->name);
841 /*****************************************************************************
845 *****************************************************************************/
849 * turns the table references specified in the from-clause into a
850 * range table. The range table may grow as we transform the expressions
851 * in the target list. (Note that this happens because in POSTQUEL, we
852 * allow references to relations not specified in the from-clause. We
853 * also allow that in our POST-SQL)
857 parseFromClause(ParseState * pstate, List * frmList)
863 RangeVar *r = lfirst(fl);
864 RelExpr *baserel = r->relExpr;
865 char *relname = baserel->relname;
866 char *refname = r->name;
873 * marks this entry to indicate it comes from the FROM clause. In
874 * SQL, the target list can only refer to range variables
875 * specified in the from clause but we follow the more powerful
876 * POSTQUEL semantics and automatically generate the range
877 * variable if not specified. However there are times we need to
878 * know whether the entries are legitimate.
880 * eg. select * from foo f where f.x = 1; will generate wrong answer
881 * if we expand * to foo.x.
883 rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
890 * make a range table with the specified relation (optional) and the
894 makeRangeTable(ParseState * pstate, char *relname, List * frmList)
898 parseFromClause(pstate, frmList);
903 if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
904 rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
906 rte = refnameRangeTableEntry(pstate->p_rtable, relname);
908 pstate->p_target_rangetblentry = rte;
909 Assert(pstate->p_target_relation == NULL);
910 pstate->p_target_relation = heap_open(rte->relid);
911 Assert(pstate->p_target_relation != NULL);
912 /* will close relation later */
917 * returns the Oid of the type of the expression. (Used for typechecking.)
920 exprType(Node * expr)
924 switch (nodeTag(expr))
927 type = ((Func *) expr)->functype;
930 type = ((Iter *) expr)->itertype;
933 type = ((Var *) expr)->vartype;
936 type = ((Expr *) expr)->typeOid;
939 type = ((Const *) expr)->consttype;
942 type = ((ArrayRef *) expr)->refelemtype;
945 type = ((Aggreg *) expr)->aggtype;
948 type = ((Param *) expr)->paramtype;
955 elog(WARN, "exprType: don't know how to get type for %d node",
964 * turns '*' (in the target list) into a list of attributes (of all
965 * relations in the range table)
968 expandAllTables(ParseState * pstate)
971 List *legit_rtable = NIL;
975 rtable = pstate->p_rtable;
976 if (pstate->p_is_rule)
980 * skip first two entries, "*new*" and "*current*"
982 rtable = lnext(lnext(pstate->p_rtable));
985 /* this should not happen */
987 elog(WARN, "cannot expand: null p_rtable");
990 * go through the range table and make a list of range table entries
991 * which we will expand.
995 RangeTblEntry *rte = lfirst(rt);
998 * we only expand those specify in the from clause. (This will
999 * also prevent us from using the wrong table in inserts: eg.
1000 * tenk2 in "insert into tenk2 select * from tenk1;")
1004 legit_rtable = lappend(legit_rtable, rte);
1007 foreach(rt, legit_rtable)
1009 RangeTblEntry *rte = lfirst(rt);
1010 List *temp = target;
1013 target = expandAll(pstate, rte->relname, rte->refname,
1014 &pstate->p_last_resno);
1017 while (temp != NIL && lnext(temp) != NIL)
1019 lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
1020 &pstate->p_last_resno);
1029 * if the name of the resulting column is not specified in the target
1030 * list, we have to guess.
1034 figureColname(Node * expr, Node * resval)
1036 switch (nodeTag(expr))
1039 return (char *) /* XXX */
1040 ((Aggreg *) expr)->aggname;
1042 if (((Expr *) expr)->opType == FUNC_EXPR)
1044 if (nodeTag(resval) == T_FuncCall)
1045 return ((FuncCall *) resval)->funcname;
1055 /*****************************************************************************
1059 *****************************************************************************/
1063 * generate a list of column names if not supplied or
1064 * test supplied column names to make sure they are in target table
1065 * (used exclusively for inserts)
1068 makeTargetNames(ParseState * pstate, List * cols)
1072 /* Generate ResTarget if not supplied */
1078 AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
1080 numcol = pstate->p_target_relation->rd_rel->relnatts;
1081 for (i = 0; i < numcol; i++)
1083 Ident *id = makeNode(Ident);
1085 id->name = palloc(NAMEDATALEN);
1086 strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN - 1);
1087 id->indirection = NIL;
1090 cols = tl = lcons(id, NIL);
1093 lnext(tl) = lcons(id, NIL);
1100 /* elog on failure */
1101 varattno(pstate->p_target_relation, ((Ident *) lfirst(tl))->name);
1107 * transformTargetList -
1108 * turns a list of ResTarget's into a list of TargetEntry's
1111 transformTargetList(ParseState * pstate, List * targetlist)
1113 List *p_target = NIL;
1114 List *tail_p_target = NIL;
1116 while (targetlist != NIL)
1118 ResTarget *res = (ResTarget *) lfirst(targetlist);
1119 TargetEntry *tent = makeNode(TargetEntry);
1121 switch (nodeTag(res->val))
1131 identname = ((Ident *) res->val)->name;
1132 handleTargetColname(pstate, &res->name, NULL, identname);
1135 * here we want to look for column names only, not
1138 /* names (even though they can be stored in Ident nodes, */
1140 expr = transformIdent(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1141 type_id = exprType(expr);
1142 type_len = tlen(get_id_type(type_id));
1143 resname = (res->name) ? res->name : identname;
1144 tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
1160 Node *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1162 handleTargetColname(pstate, &res->name, NULL, NULL);
1163 /* note indirection has not been transformed */
1164 if (pstate->p_is_insert && res->indirection != NIL)
1166 /* this is an array assignment */
1179 if (exprType(expr) != UNKNOWNOID ||
1181 elog(WARN, "yyparse: string constant expected");
1183 val = (char *) textout((struct varlena *)
1184 ((Const *) expr)->constvalue);
1185 str = save_str = (char *) palloc(strlen(val) + MAXDIM * 25 + 2);
1186 foreach(elt, res->indirection)
1188 A_Indices *aind = (A_Indices *) lfirst(elt);
1190 aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
1191 if (!IsA(aind->uidx, Const))
1193 "Array Index for Append should be a constant");
1194 uindx[i] = ((Const *) aind->uidx)->constvalue;
1195 if (aind->lidx != NULL)
1197 aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
1198 if (!IsA(aind->lidx, Const))
1200 "Array Index for Append should be a constant");
1201 lindx[i] = ((Const *) aind->lidx)->constvalue;
1207 if (lindx[i] > uindx[i])
1208 elog(WARN, "yyparse: lower index cannot be greater than upper index");
1209 sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
1213 sprintf(str, "=%s", val);
1214 rd = pstate->p_target_relation;
1216 resdomno = varattno(rd, res->name);
1217 ndims = att_attnelems(rd, resdomno);
1219 elog(WARN, "yyparse: array dimensions do not match");
1220 constval = makeNode(Value);
1221 constval->type = T_String;
1222 constval->val.str = save_str;
1223 tent = make_targetlist_expr(pstate, res->name,
1224 (Node *) make_const(constval),
1230 char *colname = res->name;
1232 /* this is not an array assignment */
1233 if (colname == NULL)
1237 * if you're wondering why this is here, look at
1238 * the yacc grammar for why a name can be missing.
1241 colname = figureColname(expr, res->val);
1243 if (res->indirection)
1245 List *ilist = res->indirection;
1247 while (ilist != NIL)
1249 A_Indices *ind = lfirst(ilist);
1251 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1252 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1253 ilist = lnext(ilist);
1256 res->name = colname;
1257 tent = make_targetlist_expr(pstate, res->name, expr,
1266 Attr *att = (Attr *) res->val;
1271 List *attrs = att->attrs;
1274 * Target item is a single '*', expand all tables (eg.
1275 * SELECT * FROM emp)
1277 if (att->relname != NULL && !strcmp(att->relname, "*"))
1279 if (tail_p_target == NIL)
1280 p_target = tail_p_target = expandAllTables(pstate);
1282 lnext(tail_p_target) = expandAllTables(pstate);
1284 while (lnext(tail_p_target) != NIL)
1285 /* make sure we point to the last target entry */
1286 tail_p_target = lnext(tail_p_target);
1289 * skip rest of while loop
1291 targetlist = lnext(targetlist);
1296 * Target item is relation.*, expand the table (eg. SELECT
1297 * emp.*, dname FROM emp, dept)
1299 attrname = strVal(lfirst(att->attrs));
1300 if (att->attrs != NIL && !strcmp(attrname, "*"))
1304 * tail_p_target is the target list we're building in
1305 * the while loop. Make sure we fix it after appending
1308 if (tail_p_target == NIL)
1309 p_target = tail_p_target = expandAll(pstate, att->relname,
1310 att->relname, &pstate->p_last_resno);
1312 lnext(tail_p_target) =
1313 expandAll(pstate, att->relname, att->relname,
1314 &pstate->p_last_resno);
1315 while (lnext(tail_p_target) != NIL)
1316 /* make sure we point to the last target entry */
1317 tail_p_target = lnext(tail_p_target);
1320 * skip the rest of the while loop
1322 targetlist = lnext(targetlist);
1328 * Target item is fully specified: ie. relation.attribute
1330 result = handleNestedDots(pstate, att, &pstate->p_last_resno);
1331 handleTargetColname(pstate, &res->name, att->relname, attrname);
1332 if (att->indirection != NIL)
1334 List *ilist = att->indirection;
1336 while (ilist != NIL)
1338 A_Indices *ind = lfirst(ilist);
1340 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1341 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1342 ilist = lnext(ilist);
1344 result = (Node *) make_array_ref(result, att->indirection);
1346 type_id = exprType(result);
1347 type_len = tlen(get_id_type(type_id));
1348 /* move to last entry */
1349 while (lnext(attrs) != NIL)
1350 attrs = lnext(attrs);
1351 resname = (res->name) ? res->name : strVal(lfirst(attrs));
1352 resnode = makeResdom((AttrNumber) pstate->p_last_resno++,
1359 tent->resdom = resnode;
1360 tent->expr = result;
1364 /* internal error */
1366 "internal error: do not know how to transform targetlist");
1370 if (p_target == NIL)
1372 p_target = tail_p_target = lcons(tent, NIL);
1376 lnext(tail_p_target) = lcons(tent, NIL);
1377 tail_p_target = lnext(tail_p_target);
1379 targetlist = lnext(targetlist);
1387 * make_targetlist_expr -
1388 * make a TargetEntry from an expression
1390 * arrayRef is a list of transformed A_Indices
1392 static TargetEntry *
1393 make_targetlist_expr(ParseState * pstate,
1409 elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
1411 type_id = exprType(expr);
1412 if (type_id == InvalidOid)
1417 type_len = tlen(get_id_type(type_id));
1419 /* I have no idea what the following does! */
1420 /* It appears to process target columns that will be receiving results */
1421 if (pstate->p_is_insert || pstate->p_is_update)
1425 * append or replace query -- append, replace work only on one
1426 * relation, so multiple occurence of same resdomno is bogus
1428 rd = pstate->p_target_relation;
1430 resdomno = varattno(rd, colname);
1431 attrisset = varisset(rd, colname);
1432 attrtype = att_typeid(rd, resdomno);
1433 if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
1434 attrtype = GetArrayElementType(attrtype);
1435 if (attrtype == BPCHAROID || attrtype == VARCHAROID)
1437 attrlen = rd->rd_att->attrs[resdomno - 1]->attlen;
1441 attrlen = tlen(get_id_type(attrtype));
1444 if (Input_is_string && Typecast_ok)
1448 if (type_id == typeid(type("unknown")))
1450 val = (Datum) textout((struct varlena *)
1451 ((Const) lnext(expr))->constvalue);
1455 val = ((Const) lnext(expr))->constvalue;
1459 lnext(expr) = makeConst(attrtype,
1472 (Datum) fmgr(typeid_get_retinfunc(attrtype),
1473 val, get_typelem(attrtype), -1),
1475 true /* Maybe correct-- 80% chance */ ,
1476 false, /* is not a set */
1480 else if ((Typecast_ok) && (attrtype != type_id))
1483 parser_typecast2(expr, get_id_type(attrtype));
1485 else if (attrtype != type_id)
1487 if ((attrtype == INT2OID) && (type_id == INT4OID))
1488 lfirst(expr) = lispInteger(INT2OID); /* handle CASHOID too */
1489 else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
1490 lfirst(expr) = lispInteger(FLOAT4OID);
1492 elog(WARN, "unequal type in tlist : %s \n", colname);
1495 Input_is_string = false;
1496 Input_is_integer = false;
1500 if (attrtype != type_id)
1502 if (IsA(expr, Const))
1504 /* try to cast the constant */
1505 if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
1507 /* updating a single item */
1508 Oid typelem = get_typelem(attrtype);
1510 expr = (Node *) parser_typecast2(expr,
1512 get_id_type(typelem),
1516 expr = (Node *) parser_typecast2(expr,
1518 get_id_type(attrtype),
1523 /* currently, we can't handle casting of expressions */
1524 elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
1526 get_id_typname(attrtype),
1527 get_id_typname(type_id));
1531 if (arrayRef != NIL)
1534 Attr *att = makeNode(Attr);
1535 List *ar = arrayRef;
1536 List *upperIndexpr = NIL;
1537 List *lowerIndexpr = NIL;
1539 att->relname = pstrdup(RelationGetRelationName(rd)->data);
1540 att->attrs = lcons(makeString(colname), NIL);
1541 target_expr = (Expr *) handleNestedDots(pstate, att,
1542 &pstate->p_last_resno);
1545 A_Indices *ind = lfirst(ar);
1547 if (lowerIndexpr || (!upperIndexpr && ind->lidx))
1551 * XXX assume all lowerIndexpr is non-null in this
1554 lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
1556 upperIndexpr = lappend(upperIndexpr, ind->uidx);
1560 expr = (Node *) make_array_set(target_expr,
1564 attrtype = att_typeid(rd, resdomno);
1565 attrlen = tlen(get_id_type(attrtype));
1570 resdomno = pstate->p_last_resno++;
1574 tent = makeNode(TargetEntry);
1576 resnode = makeResdom((AttrNumber) resdomno,
1584 tent->resdom = resnode;
1591 /*****************************************************************************
1595 *****************************************************************************/
1598 * transformWhereClause -
1599 * transforms the qualification and make sure it is of type Boolean
1603 transformWhereClause(ParseState * pstate, Node * a_expr)
1608 return (Node *) NULL; /* no qualifiers */
1610 inWhereClause = true;
1611 qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
1612 inWhereClause = false;
1613 if (exprType(qual) != BOOLOID)
1616 "where clause must return type bool, not %s",
1617 tname(get_id_type(exprType(qual))));
1622 /*****************************************************************************
1626 *****************************************************************************/
1629 * find_targetlist_entry -
1630 * returns the Resdom in the target list matching the specified varname
1634 static TargetEntry *
1635 find_targetlist_entry(ParseState * pstate, SortGroupBy * sortgroupby, List * tlist)
1638 int real_rtable_pos = 0,
1640 TargetEntry *target_result = NULL;
1642 if (sortgroupby->range)
1643 real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
1644 sortgroupby->range);
1648 TargetEntry *target = (TargetEntry *) lfirst(i);
1649 Resdom *resnode = target->resdom;
1650 Var *var = (Var *) target->expr;
1651 char *resname = resnode->resname;
1652 int test_rtable_pos = var->varno;
1655 printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
1656 (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno);
1659 if (!sortgroupby->name)
1661 if (sortgroupby->resno == ++target_pos)
1663 target_result = target;
1669 if (!strcmp(resname, sortgroupby->name))
1671 if (sortgroupby->range)
1673 if (real_rtable_pos == test_rtable_pos)
1675 if (target_result != NULL)
1676 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1678 target_result = target;
1683 if (target_result != NULL)
1684 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1686 target_result = target;
1691 return target_result;
1695 any_ordering_op(int restype)
1700 order_op = oper("<", restype, restype, false);
1701 order_opid = oprid(order_op);
1707 * transformGroupClause -
1708 * transform a Group By clause
1712 transformGroupClause(ParseState * pstate, List * grouplist, List * targetlist)
1717 while (grouplist != NIL)
1719 GroupClause *grpcl = makeNode(GroupClause);
1720 TargetEntry *restarget;
1723 restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
1725 if (restarget == NULL)
1726 elog(WARN, "The field being grouped by must appear in the target list");
1728 grpcl->entry = restarget;
1729 resdom = restarget->resdom;
1730 grpcl->grpOpoid = oprid(oper("<",
1732 resdom->restype, false));
1734 gl = glist = lcons(grpcl, NIL);
1737 lnext(gl) = lcons(grpcl, NIL);
1740 grouplist = lnext(grouplist);
1747 * transformSortClause -
1748 * transform an Order By clause
1752 transformSortClause(ParseState * pstate,
1753 List * orderlist, List * targetlist,
1756 List *sortlist = NIL;
1760 while (orderlist != NIL)
1762 SortGroupBy *sortby = lfirst(orderlist);
1763 SortClause *sortcl = makeNode(SortClause);
1764 TargetEntry *restarget;
1767 restarget = find_targetlist_entry(pstate, sortby, targetlist);
1768 if (restarget == NULL)
1769 elog(WARN, "The field being ordered by must appear in the target list");
1771 sortcl->resdom = resdom = restarget->resdom;
1772 sortcl->opoid = oprid(oper(sortby->useOp,
1774 resdom->restype, false));
1775 if (sortlist == NIL)
1777 s = sortlist = lcons(sortcl, NIL);
1781 lnext(s) = lcons(sortcl, NIL);
1784 orderlist = lnext(orderlist);
1789 if (uniqueFlag[0] == '*')
1793 * concatenate all elements from target list that are not
1794 * already in the sortby list
1796 foreach(i, targetlist)
1798 TargetEntry *tlelt = (TargetEntry *) lfirst(i);
1803 SortClause *sortcl = lfirst(s);
1805 if (sortcl->resdom == tlelt->resdom)
1811 /* not a member of the sortclauses yet */
1812 SortClause *sortcl = makeNode(SortClause);
1814 sortcl->resdom = tlelt->resdom;
1815 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1817 sortlist = lappend(sortlist, sortcl);
1823 TargetEntry *tlelt = NULL;
1824 char *uniqueAttrName = uniqueFlag;
1826 /* only create sort clause with the specified unique attribute */
1827 foreach(i, targetlist)
1829 tlelt = (TargetEntry *) lfirst(i);
1830 if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
1835 elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
1838 foreach(s, sortlist)
1840 SortClause *sortcl = lfirst(s);
1842 if (sortcl->resdom == tlelt->resdom)
1847 /* not a member of the sortclauses yet */
1848 SortClause *sortcl = makeNode(SortClause);
1850 sortcl->resdom = tlelt->resdom;
1851 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1853 sortlist = lappend(sortlist, sortcl);
1863 ** HandleNestedDots --
1864 ** Given a nested dot expression (i.e. (relation func ... attr), build up
1865 ** a tree with of Iter and Func nodes.
1868 handleNestedDots(ParseState * pstate, Attr * attr, int *curr_resno)
1871 Node *retval = NULL;
1873 if (attr->paramNo != NULL)
1875 Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
1878 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1884 Ident *ident = makeNode(Ident);
1886 ident->name = attr->relname;
1887 ident->isRel = TRUE;
1889 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1894 foreach(mutator_iter, lnext(attr->attrs))
1896 retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)),
1905 ** make_arguments --
1906 ** Given the number and types of arguments to a function, and the
1907 ** actual arguments and argument types, do the necessary typecasting.
1910 make_arguments(int nargs,
1912 Oid * input_typeids,
1913 Oid * function_typeids)
1917 * there are two ways an input typeid can differ from a function
1918 * typeid : either the input type inherits the function type, so no
1919 * typecasting is necessary, or the input type can be typecast into
1920 * the function type. right now, we only typecast unknowns, and that
1921 * is all we check for.
1924 List *current_fargs;
1927 for (i = 0, current_fargs = fargs;
1929 i++, current_fargs = lnext(current_fargs))
1932 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
1934 lfirst(current_fargs) =
1935 parser_typecast2(lfirst(current_fargs),
1937 get_id_type(function_typeids[i]),
1945 ** Build a tlist that says which attribute to project to.
1946 ** This routine is called by ParseFunc() to set up a target list
1947 ** on a tuple parameter or return value. Due to a bug in 4.0,
1948 ** it's not possible to refer to system attributes in this case.
1951 setup_tlist(char *attname, Oid relid)
1959 attno = get_attnum(relid, attname);
1961 elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
1963 typeid = find_atttype(relid, attname);
1964 resnode = makeResdom(1,
1966 tlen(get_id_type(typeid)),
1967 get_attname(relid, attno),
1971 varnode = makeVar(-1, attno, typeid, -1, attno);
1973 tle = makeNode(TargetEntry);
1974 tle->resdom = resnode;
1975 tle->expr = (Node *) varnode;
1976 return (lcons(tle, NIL));
1980 ** setup_base_tlist --
1981 ** Build a tlist that extracts a base type from the tuple
1982 ** returned by the executor.
1985 setup_base_tlist(Oid typeid)
1991 resnode = makeResdom(1,
1993 tlen(get_id_type(typeid)),
1998 varnode = makeVar(-1, 1, typeid, -1, 1);
1999 tle = makeNode(TargetEntry);
2000 tle->resdom = resnode;
2001 tle->expr = (Node *) varnode;
2003 return (lcons(tle, NIL));
2007 * ParseComplexProjection -
2008 * handles function calls with a single argument that is of complex type.
2009 * This routine returns NULL if it can't handle the projection (eg. sets).
2012 ParseComplexProjection(ParseState * pstate,
2024 switch (nodeTag(first_arg))
2031 iter = (Iter *) first_arg;
2032 func = (Func *) ((Expr *) iter->iterexpr)->oper;
2033 argtype = funcid_get_rettype(func->funcid);
2034 argrelid = typeid_get_relid(argtype);
2036 ((attnum = get_attnum(argrelid, funcname))
2037 != InvalidAttrNumber))
2041 * the argument is a function returning a tuple, so
2042 * funcname may be a projection
2045 /* add a tlist to the func node and return the Iter */
2046 rd = heap_openr(tname(get_id_type(argtype)));
2047 if (RelationIsValid(rd))
2049 relid = RelationGetRelationId(rd);
2050 relname = RelationGetRelationName(rd);
2053 if (RelationIsValid(rd))
2056 setup_tlist(funcname, argrelid);
2057 iter->itertype = att_typeid(rd, attnum);
2058 return ((Node *) iter);
2063 "Function %s has bad returntype %d",
2078 * The argument is a set, so this is either a projection or a
2079 * function call on this set.
2086 Expr *expr = (Expr *) first_arg;
2089 if (expr->opType != FUNC_EXPR)
2092 funcnode = (Func *) expr->oper;
2093 argtype = funcid_get_rettype(funcnode->funcid);
2094 argrelid = typeid_get_relid(argtype);
2097 * the argument is a function returning a tuple, so funcname
2098 * may be a projection
2101 (attnum = get_attnum(argrelid, funcname))
2102 != InvalidAttrNumber)
2105 /* add a tlist to the func node */
2106 rd = heap_openr(tname(get_id_type(argtype)));
2107 if (RelationIsValid(rd))
2109 relid = RelationGetRelationId(rd);
2110 relname = RelationGetRelationName(rd);
2113 if (RelationIsValid(rd))
2117 funcnode->func_tlist =
2118 setup_tlist(funcname, argrelid);
2119 funcnode->functype = att_typeid(rd, attnum);
2121 newexpr = makeNode(Expr);
2122 newexpr->typeOid = funcnode->functype;
2123 newexpr->opType = FUNC_EXPR;
2124 newexpr->oper = (Node *) funcnode;
2125 newexpr->args = lcons(first_arg, NIL);
2127 return ((Node *) newexpr);
2132 elog(WARN, "Function %s has bad returntype %d",
2138 Param *param = (Param *) first_arg;
2141 * If the Param is a complex type, this could be a projection
2143 rd = heap_openr(tname(get_id_type(param->paramtype)));
2144 if (RelationIsValid(rd))
2146 relid = RelationGetRelationId(rd);
2147 relname = RelationGetRelationName(rd);
2150 if (RelationIsValid(rd) &&
2151 (attnum = get_attnum(relid, funcname))
2152 != InvalidAttrNumber)
2155 param->paramtype = att_typeid(rd, attnum);
2156 param->param_tlist = setup_tlist(funcname, relid);
2157 return ((Node *) param);
2169 ParseFunc(ParseState * pstate, char *funcname, List * fargs, int *curr_resno)
2171 Oid rettype = (Oid) 0;
2172 Oid argrelid = (Oid) 0;
2173 Oid funcid = (Oid) 0;
2175 Node *first_arg = NULL;
2176 char *relname = NULL;
2177 char *refname = NULL;
2183 Oid *true_oid_array;
2187 bool attisset = false;
2193 first_arg = lfirst(fargs);
2194 if (first_arg == NULL)
2195 elog(WARN, "function %s does not allow NULL input", funcname);
2199 * * check for projection methods: if function takes one argument, and *
2200 * that argument is a relation, param, or PQ function returning a
2201 * complex * type, then the function could be a projection.
2203 if (length(fargs) == 1)
2206 if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
2209 Ident *ident = (Ident *) first_arg;
2212 * first arg is a relation. This could be a projection.
2214 refname = ident->name;
2216 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2218 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
2220 relname = rte->relname;
2224 * If the attr isn't a set, just make a var for it. If it is
2225 * a set, treat it like a function and drop through.
2227 if (get_attnum(relid, funcname) != InvalidAttrNumber)
2232 ((Node *) make_var(pstate,
2239 /* drop through - attr is a set */
2243 else if (ISCOMPLEX(exprType(first_arg)))
2247 * Attempt to handle projection of a complex argument. If
2248 * ParseComplexProjection can't handle the projection, we have
2251 retval = ParseComplexProjection(pstate,
2257 toid = exprType(first_arg);
2258 rd = heap_openr(tname(get_id_type(toid)));
2259 if (RelationIsValid(rd))
2261 relname = RelationGetRelationName(rd)->data;
2266 "Type %s is not a relation type",
2267 tname(get_id_type(toid)));
2268 argrelid = typeid_get_relid(toid);
2271 * A projection contains either an attribute name or the
2274 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
2275 && strcmp(funcname, "*"))
2277 elog(WARN, "Functions on sets are not yet supported");
2288 * Parsing aggregates.
2293 * the aggregate count is a special case, ignore its base
2294 * type. Treat it as zero
2296 if (strcmp(funcname, "count") == 0)
2299 basetype = exprType(lfirst(fargs));
2300 if (SearchSysCacheTuple(AGGNAME,
2301 PointerGetDatum(funcname),
2302 ObjectIdGetDatum(basetype),
2305 Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
2307 AddAggToParseState(pstate, aggreg);
2308 return (Node *) aggreg;
2315 * * If we dropped through to here it's really a function (or a set,
2316 * which * is implemented as a function.) * extract arg type info and
2317 * transform relation name arguments into * varnodes of the
2320 memset(&oid_array[0], 0, 8 * sizeof(Oid));
2327 Node *pair = lfirst(i);
2329 if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
2335 refname = ((Ident *) pair)->name;
2337 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2339 rte = addRangeTableEntry(pstate, refname, refname,
2340 FALSE, FALSE, NULL);
2341 relname = rte->relname;
2343 vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname);
2346 * for func(relname), the param to the function is the tuple
2347 * under consideration. we build a special VarNode to reflect
2348 * this -- it has varno set to the correct range table entry,
2349 * but has varattno == 0 to signal that the whole tuple is the
2352 toid = typeid(type(relname));
2353 /* replace it in the arg list */
2355 makeVar(vnum, 0, toid, vnum, 0);
2358 { /* set functions don't have parameters */
2361 * any functiona args which are typed "unknown", but aren't
2362 * constants, we don't know what to do with, because we can't
2365 if (exprType(pair) == UNKNOWNOID &&
2368 elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
2371 toid = exprType(pair);
2374 oid_array[nargs++] = toid;
2378 * func_get_detail looks up the function in the catalogs, does
2379 * disambiguation for polymorphic functions, handles inheritance, and
2380 * returns the funcid and type and set or singleton status of the
2381 * function's return value. it also returns the true argument types
2382 * to the function. if func_get_detail returns true, the function
2383 * exists. otherwise, there was an error.
2386 { /* we know all of these fields already */
2389 * We create a funcnode with a placeholder function SetEval.
2390 * SetEval() never actually gets executed. When the function
2391 * evaluation routines see it, they use the funcid projected out
2392 * from the relation as the actual function to call. Example:
2393 * retrieve (emp.mgr.name) The plan for this will scan the emp
2394 * relation, projecting out the mgr attribute, which is a funcid.
2395 * This function is then called (instead of SetEval) and "name" is
2396 * projected from its result.
2398 funcid = SetEvalRegProcedure;
2401 true_oid_array = oid_array;
2406 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
2407 &rettype, &retset, &true_oid_array);
2411 elog(WARN, "no such attribute or function %s", funcname);
2414 funcnode = makeNode(Func);
2415 funcnode->funcid = funcid;
2416 funcnode->functype = rettype;
2417 funcnode->funcisindex = false;
2418 funcnode->funcsize = 0;
2419 funcnode->func_fcache = NULL;
2420 funcnode->func_tlist = NIL;
2421 funcnode->func_planlist = NIL;
2423 /* perform the necessary typecasting */
2424 make_arguments(nargs, fargs, oid_array, true_oid_array);
2427 * for functions returning base types, we want to project out the
2428 * return value. set up a target list to do that. the executor will
2429 * ignore these for c functions, and do the right thing for postquel
2433 if (typeid_get_relid(rettype) == InvalidOid)
2434 funcnode->func_tlist = setup_base_tlist(rettype);
2437 * For sets, we want to make a targetlist to project out this
2438 * attribute of the set tuples.
2442 if (!strcmp(funcname, "*"))
2444 funcnode->func_tlist =
2445 expandAll(pstate, relname, refname, curr_resno);
2449 funcnode->func_tlist = setup_tlist(funcname, argrelid);
2450 rettype = find_atttype(argrelid, funcname);
2455 * Sequence handling.
2457 if (funcid == SeqNextValueRegProcedure ||
2458 funcid == SeqCurrValueRegProcedure)
2462 int32 aclcheck_result = -1;
2464 Assert(length(fargs) == 1);
2465 seq = (Const *) lfirst(fargs);
2466 if (!IsA((Node *) seq, Const))
2467 elog(WARN, "%s: only constant sequence names are acceptable", funcname);
2468 seqrel = textout((struct varlena *) (seq->constvalue));
2470 if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
2471 ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)))
2473 elog(WARN, "%s.%s: %s",
2474 seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
2478 if (funcid == SeqNextValueRegProcedure && inWhereClause)
2479 elog(WARN, "nextval of a sequence in WHERE disallowed");
2482 expr = makeNode(Expr);
2483 expr->typeOid = rettype;
2484 expr->opType = FUNC_EXPR;
2485 expr->oper = (Node *) funcnode;
2487 retval = (Node *) expr;
2490 * if the function returns a set of values, then we need to iterate
2491 * over all the returned values in the executor, so we stick an iter
2492 * node here. if it returns a singleton, then we don't need the iter
2498 Iter *iter = makeNode(Iter);
2500 iter->itertype = rettype;
2501 iter->iterexpr = retval;
2502 retval = (Node *) iter;
2508 /*****************************************************************************
2510 *****************************************************************************/
2513 * AddAggToParseState -
2514 * add the aggregate to the list of unique aggregates in pstate.
2516 * SIDE EFFECT: aggno in target list entry will be modified
2519 AddAggToParseState(ParseState * pstate, Aggreg * aggreg)
2525 * see if we have the aggregate already (we only need to record the
2529 foreach(ag, pstate->p_aggs)
2531 Aggreg *a = lfirst(ag);
2533 if (!strcmp(a->aggname, aggreg->aggname) &&
2534 equal(a->target, aggreg->target))
2537 /* fill in the aggno and we're done */
2544 /* not found, new aggregate */
2547 pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
2552 * finalizeAggregates -
2553 * fill in qry_aggs from pstate. Also checks to make sure that aggregates
2554 * are used in the proper place.
2557 finalizeAggregates(ParseState * pstate, Query * qry)
2562 parseCheckAggregates(pstate, qry);
2564 qry->qry_numAgg = pstate->p_numAgg;
2566 (Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
2568 foreach(l, pstate->p_aggs)
2569 qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
2573 * contain_agg_clause--
2574 * Recursively find aggreg nodes from a clause.
2576 * Returns true if any aggregate found.
2579 contain_agg_clause(Node * clause)
2583 else if (IsA(clause, Aggreg))
2585 else if (IsA(clause, Iter))
2586 return contain_agg_clause(((Iter *) clause)->iterexpr);
2587 else if (single_node(clause))
2589 else if (or_clause(clause))
2593 foreach(temp, ((Expr *) clause)->args)
2594 if (contain_agg_clause(lfirst(temp)))
2598 else if (is_funcclause(clause))
2602 foreach(temp, ((Expr *) clause)->args)
2603 if (contain_agg_clause(lfirst(temp)))
2607 else if (IsA(clause, ArrayRef))
2611 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
2612 if (contain_agg_clause(lfirst(temp)))
2614 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
2615 if (contain_agg_clause(lfirst(temp)))
2617 if (contain_agg_clause(((ArrayRef *) clause)->refexpr))
2619 if (contain_agg_clause(((ArrayRef *) clause)->refassgnexpr))
2623 else if (not_clause(clause))
2624 return contain_agg_clause((Node *) get_notclausearg((Expr *) clause));
2625 else if (is_opclause(clause))
2626 return (contain_agg_clause((Node *) get_leftop((Expr *) clause)) ||
2627 contain_agg_clause((Node *) get_rightop((Expr *) clause)));
2633 * exprIsAggOrGroupCol -
2634 * returns true if the expression does not contain non-group columns.
2637 exprIsAggOrGroupCol(Node * expr, List * groupClause)
2641 if (expr == NULL || IsA(expr, Const) ||
2642 IsA(expr, Param) || IsA(expr, Aggreg))
2645 foreach(gl, groupClause)
2647 GroupClause *grpcl = lfirst(gl);
2649 if (equal(expr, grpcl->entry->expr))
2653 if (IsA(expr, Expr))
2657 foreach(temp, ((Expr *) expr)->args)
2658 if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2667 * tleIsAggOrGroupCol -
2668 * returns true if the TargetEntry is Agg or GroupCol.
2671 tleIsAggOrGroupCol(TargetEntry * tle, List * groupClause)
2673 Node *expr = tle->expr;
2676 if (expr == NULL || IsA(expr, Const) || IsA(expr, Param))
2679 foreach(gl, groupClause)
2681 GroupClause *grpcl = lfirst(gl);
2683 if (tle->resdom->resno == grpcl->entry->resdom->resno)
2685 if (contain_agg_clause((Node *) expr))
2686 elog(WARN, "parser: aggregates not allowed in GROUP BY clause");
2691 if (IsA(expr, Aggreg))
2694 if (IsA(expr, Expr))
2698 foreach(temp, ((Expr *) expr)->args)
2699 if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2708 * parseCheckAggregates -
2709 * this should really be done earlier but the current grammar
2710 * cannot differentiate functions from aggregates. So we have do check
2711 * here when the target list and the qualifications are finalized.
2714 parseCheckAggregates(ParseState * pstate, Query * qry)
2718 Assert(pstate->p_numAgg > 0);
2721 * aggregates never appear in WHERE clauses. (we have to check where
2722 * clause first because if there is an aggregate, the check for
2723 * non-group column in target list may fail.)
2725 if (contain_agg_clause(qry->qual))
2726 elog(WARN, "parser: aggregates not allowed in WHERE clause");
2729 * the target list can only contain aggregates, group columns and
2730 * functions thereof.
2732 foreach(tl, qry->targetList)
2734 TargetEntry *tle = lfirst(tl);
2736 if (!tleIsAggOrGroupCol(tle, qry->groupClause))
2738 "parser: illegal use of aggregates or non-group column in target list");
2742 * the expression specified in the HAVING clause has the same
2743 * restriction as those in the target list.
2746 * Need to change here when we get HAVING works. Currently
2747 * qry->havingQual is NULL. - vadim 04/05/97
2748 if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
2750 "parser: illegal use of aggregates or non-group column in HAVING clause");