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.43 1997/09/18 14:32:15 vadim 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
208 * context because vacuum spans transactions and we don't
209 * want to lose the vacuum Query due to end-of-transaction
212 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
213 result = makeNode(Query);
214 result->commandType = CMD_UTILITY;
215 result->utilityStmt = (Node *) parseTree;
216 MemoryContextSwitchTo(oldcontext);
222 ExplainStmt *n = (ExplainStmt *) parseTree;
224 result = makeNode(Query);
225 result->commandType = CMD_UTILITY;
226 n->query = transformStmt(pstate, (Node *) n->query);
227 result->utilityStmt = (Node *) parseTree;
231 /*------------------------
232 * Optimizable statements
233 *------------------------
236 result = transformInsertStmt(pstate, (AppendStmt *) parseTree);
240 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
244 result = transformUpdateStmt(pstate, (ReplaceStmt *) parseTree);
248 result = transformCursorStmt(pstate, (CursorStmt *) parseTree);
252 result = transformSelectStmt(pstate, (RetrieveStmt *) parseTree);
258 * other statments don't require any transformation-- just
259 * return the original parsetree
261 result = makeNode(Query);
262 result->commandType = CMD_UTILITY;
263 result->utilityStmt = (Node *) parseTree;
270 * transformDeleteStmt -
271 * transforms a Delete Statement
274 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
276 Query *qry = makeNode(Query);
278 qry->commandType = CMD_DELETE;
280 /* set up a range table */
281 makeRangeTable(pstate, stmt->relname, NULL);
283 qry->uniqueFlag = NULL;
285 /* fix where clause */
286 qry->qual = transformWhereClause(pstate, stmt->whereClause);
288 qry->rtable = pstate->p_rtable;
289 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
291 /* make sure we don't have aggregates in the where clause */
292 if (pstate->p_numAgg > 0)
293 parseCheckAggregates(pstate, qry);
295 return (Query *) qry;
299 * transformInsertStmt -
300 * transform an Insert Statement
303 transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
305 Query *qry = makeNode(Query); /* make a new query tree */
307 qry->commandType = CMD_INSERT;
308 pstate->p_is_insert = true;
310 /* set up a range table */
311 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
313 qry->uniqueFlag = NULL;
315 /* fix the target list */
316 pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
318 qry->targetList = transformTargetList(pstate, stmt->targetList);
320 /* fix where clause */
321 qry->qual = transformWhereClause(pstate, stmt->whereClause);
323 /* now the range table will not change */
324 qry->rtable = pstate->p_rtable;
325 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
327 if (pstate->p_numAgg > 0)
328 finalizeAggregates(pstate, qry);
330 return (Query *) qry;
334 * transformIndexStmt -
335 * transforms the qualification of the index statement
338 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
343 q->commandType = CMD_UTILITY;
345 /* take care of the where clause */
346 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
347 stmt->rangetable = pstate->p_rtable;
349 q->utilityStmt = (Node *) stmt;
355 * transformExtendStmt -
356 * transform the qualifications of the Extend Index Statement
360 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
365 q->commandType = CMD_UTILITY;
367 /* take care of the where clause */
368 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
369 stmt->rangetable = pstate->p_rtable;
371 q->utilityStmt = (Node *) stmt;
376 * transformRuleStmt -
377 * transform a Create Rule Statement. The actions is a list of parse
378 * trees which is transformed into a list of query trees.
381 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
387 q->commandType = CMD_UTILITY;
389 actions = stmt->actions;
392 * transform each statment, like parse_analyze()
394 while (actions != NIL)
398 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
401 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
403 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
406 pstate->p_last_resno = 1;
407 pstate->p_is_rule = true; /* for expand all */
408 pstate->p_numAgg = 0;
409 pstate->p_aggs = NULL;
411 lfirst(actions) = transformStmt(pstate, lfirst(actions));
412 actions = lnext(actions);
415 /* take care of the where clause */
416 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
418 q->utilityStmt = (Node *) stmt;
424 * transformSelectStmt -
425 * transforms a Select Statement
429 transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
431 Query *qry = makeNode(Query);
433 qry->commandType = CMD_SELECT;
435 /* set up a range table */
436 makeRangeTable(pstate, NULL, stmt->fromClause);
438 qry->uniqueFlag = stmt->unique;
440 qry->into = stmt->into;
441 qry->isPortal = FALSE;
443 /* fix the target list */
444 qry->targetList = transformTargetList(pstate, stmt->targetList);
446 /* fix where clause */
447 qry->qual = transformWhereClause(pstate, stmt->whereClause);
449 /* check subselect clause */
450 if (stmt->selectClause)
451 elog(NOTICE, "UNION not yet supported; using first SELECT only", NULL);
453 /* check subselect clause */
454 if (stmt->havingClause)
455 elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
457 /* fix order clause */
458 qry->sortClause = transformSortClause(pstate,
463 /* fix group by clause */
464 qry->groupClause = transformGroupClause(pstate,
467 qry->rtable = pstate->p_rtable;
469 if (pstate->p_numAgg > 0)
470 finalizeAggregates(pstate, qry);
472 return (Query *) qry;
476 * transformUpdateStmt -
477 * transforms an update statement
481 transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt)
483 Query *qry = makeNode(Query);
485 qry->commandType = CMD_UPDATE;
486 pstate->p_is_update = true;
489 * the FROM clause is non-standard SQL syntax. We used to be able to
490 * do this with REPLACE in POSTQUEL so we keep the feature.
492 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
494 /* fix the target list */
495 qry->targetList = transformTargetList(pstate, stmt->targetList);
497 /* fix where clause */
498 qry->qual = transformWhereClause(pstate, stmt->whereClause);
500 qry->rtable = pstate->p_rtable;
501 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
503 /* make sure we don't have aggregates in the where clause */
504 if (pstate->p_numAgg > 0)
505 parseCheckAggregates(pstate, qry);
507 return (Query *) qry;
511 * transformCursorStmt -
512 * transform a Create Cursor Statement
516 transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
518 Query *qry = makeNode(Query);
521 * in the old days, a cursor statement is a 'retrieve into portal'; If
522 * you change the following, make sure you also go through the code in
523 * various places that tests the kind of operation.
525 qry->commandType = CMD_SELECT;
527 /* set up a range table */
528 makeRangeTable(pstate, NULL, stmt->fromClause);
530 qry->uniqueFlag = stmt->unique;
532 qry->into = stmt->portalname;
533 qry->isPortal = TRUE;
534 qry->isBinary = stmt->binary; /* internal portal */
536 /* fix the target list */
537 qry->targetList = transformTargetList(pstate, stmt->targetList);
539 /* fix where clause */
540 qry->qual = transformWhereClause(pstate, stmt->whereClause);
542 /* fix order clause */
543 qry->sortClause = transformSortClause(pstate,
547 /* fix group by clause */
548 qry->groupClause = transformGroupClause(pstate,
552 qry->rtable = pstate->p_rtable;
554 if (pstate->p_numAgg > 0)
555 finalizeAggregates(pstate, qry);
557 return (Query *) qry;
560 /*****************************************************************************
562 * Transform Exprs, Aggs, etc.
564 *****************************************************************************/
568 * analyze and transform expressions. Type checking and type casting is
569 * done here. The optimizer and the executor cannot handle the original
570 * (raw) expressions collected by the parse tree. Hence the transformation
574 transformExpr(ParseState *pstate, Node *expr, int precedence)
581 switch (nodeTag(expr))
585 Attr *att = (Attr *) expr;
588 /* what if att.attrs == "*"?? */
589 temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
590 if (att->indirection != NIL)
592 List *idx = att->indirection;
596 A_Indices *ai = (A_Indices *) lfirst(idx);
600 uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
601 if (exprType(uexpr) != INT4OID)
602 elog(WARN, "array index expressions must be int4's");
603 if (ai->lidx != NULL)
605 lexpr = transformExpr(pstate, ai->lidx, precedence);
606 if (exprType(lexpr) != INT4OID)
607 elog(WARN, "array index expressions must be int4's");
611 if (ai->lidx != NULL)
618 * note we reuse the list of indices, make sure we
619 * don't free them! Otherwise, make a new list
624 result = (Node *) make_array_ref(temp, att->indirection);
634 A_Const *con = (A_Const *) expr;
635 Value *val = &con->val;
637 if (con->typename != NULL)
639 result = parser_typecast(val, con->typename, -1);
643 result = (Node *) make_const(val);
649 ParamNo *pno = (ParamNo *) expr;
654 paramno = pno->number;
655 toid = param_type(paramno);
656 if (!OidIsValid(toid))
658 elog(WARN, "Parameter '$%d' is out of range",
661 param = makeNode(Param);
662 param->paramkind = PARAM_NUM;
663 param->paramid = (AttrNumber) paramno;
664 param->paramname = "<unnamed>";
665 param->paramtype = (Oid) toid;
666 param->param_tlist = (List *) NULL;
668 result = (Node *) param;
673 A_Expr *a = (A_Expr *) expr;
679 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
680 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
682 result = (Node *) make_op(a->opname, lexpr, rexpr);
687 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
689 result = ParseFunc(pstate,
690 "nullvalue", lcons(lexpr, NIL),
691 &pstate->p_last_resno);
696 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
698 result = ParseFunc(pstate,
699 "nonnullvalue", lcons(lexpr, NIL),
700 &pstate->p_last_resno);
705 Expr *expr = makeNode(Expr);
706 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
707 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
709 if (exprType(lexpr) != BOOLOID)
711 "left-hand side of AND is type '%s', not bool",
712 tname(get_id_type(exprType(lexpr))));
713 if (exprType(rexpr) != BOOLOID)
715 "right-hand side of AND is type '%s', not bool",
716 tname(get_id_type(exprType(rexpr))));
717 expr->typeOid = BOOLOID;
718 expr->opType = AND_EXPR;
719 expr->args = makeList(lexpr, rexpr, -1);
720 result = (Node *) expr;
725 Expr *expr = makeNode(Expr);
726 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
727 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
729 if (exprType(lexpr) != BOOLOID)
731 "left-hand side of OR is type '%s', not bool",
732 tname(get_id_type(exprType(lexpr))));
733 if (exprType(rexpr) != BOOLOID)
735 "right-hand side of OR is type '%s', not bool",
736 tname(get_id_type(exprType(rexpr))));
737 expr->typeOid = BOOLOID;
738 expr->opType = OR_EXPR;
739 expr->args = makeList(lexpr, rexpr, -1);
740 result = (Node *) expr;
745 Expr *expr = makeNode(Expr);
746 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
748 if (exprType(rexpr) != BOOLOID)
750 "argument to NOT is type '%s', not bool",
751 tname(get_id_type(exprType(rexpr))));
752 expr->typeOid = BOOLOID;
753 expr->opType = NOT_EXPR;
754 expr->args = makeList(rexpr, -1);
755 result = (Node *) expr;
765 * look for a column name or a relation name (the default
768 result = transformIdent(pstate, expr, precedence);
773 FuncCall *fn = (FuncCall *) expr;
776 /* transform the list of arguments */
777 foreach(args, fn->args)
778 lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
779 result = ParseFunc(pstate,
780 fn->funcname, fn->args, &pstate->p_last_resno);
784 /* should not reach here */
785 elog(WARN, "transformExpr: does not know how to transform %d\n",
794 transformIdent(ParseState *pstate, Node *expr, int precedence)
796 Ident *ident = (Ident *) expr;
802 column_result = relation_result = result = 0;
803 /* try to find the ident as a column */
804 if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
806 Attr *att = makeNode(Attr);
808 att->relname = rte->refname;
809 att->attrs = lcons(makeString(ident->name), NIL);
811 (Node *) handleNestedDots(pstate, att, &pstate->p_last_resno);
814 /* try to find the ident as a relation */
815 if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL)
818 relation_result = (Node *) ident;
821 /* choose the right result based on the precedence */
822 if (precedence == EXPR_COLUMN_FIRST)
825 result = column_result;
827 result = relation_result;
832 result = relation_result;
834 result = column_result;
838 elog(WARN, "attribute \"%s\" not found", ident->name);
843 /*****************************************************************************
847 *****************************************************************************/
851 * turns the table references specified in the from-clause into a
852 * range table. The range table may grow as we transform the expressions
853 * in the target list. (Note that this happens because in POSTQUEL, we
854 * allow references to relations not specified in the from-clause. We
855 * also allow that in our POST-SQL)
859 parseFromClause(ParseState *pstate, List *frmList)
865 RangeVar *r = lfirst(fl);
866 RelExpr *baserel = r->relExpr;
867 char *relname = baserel->relname;
868 char *refname = r->name;
875 * marks this entry to indicate it comes from the FROM clause. In
876 * SQL, the target list can only refer to range variables
877 * specified in the from clause but we follow the more powerful
878 * POSTQUEL semantics and automatically generate the range
879 * variable if not specified. However there are times we need to
880 * know whether the entries are legitimate.
882 * eg. select * from foo f where f.x = 1; will generate wrong answer
883 * if we expand * to foo.x.
885 rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
892 * make a range table with the specified relation (optional) and the
896 makeRangeTable(ParseState *pstate, char *relname, List *frmList)
900 parseFromClause(pstate, frmList);
905 if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
906 rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
908 rte = refnameRangeTableEntry(pstate->p_rtable, relname);
910 pstate->p_target_rangetblentry = rte;
911 Assert(pstate->p_target_relation == NULL);
912 pstate->p_target_relation = heap_open(rte->relid);
913 Assert(pstate->p_target_relation != NULL);
914 /* will close relation later */
919 * returns the Oid of the type of the expression. (Used for typechecking.)
926 switch (nodeTag(expr))
929 type = ((Func *) expr)->functype;
932 type = ((Iter *) expr)->itertype;
935 type = ((Var *) expr)->vartype;
938 type = ((Expr *) expr)->typeOid;
941 type = ((Const *) expr)->consttype;
944 type = ((ArrayRef *) expr)->refelemtype;
947 type = ((Aggreg *) expr)->aggtype;
950 type = ((Param *) expr)->paramtype;
957 elog(WARN, "exprType: don't know how to get type for %d node",
966 * turns '*' (in the target list) into a list of attributes (of all
967 * relations in the range table)
970 expandAllTables(ParseState *pstate)
973 List *legit_rtable = NIL;
977 rtable = pstate->p_rtable;
978 if (pstate->p_is_rule)
982 * skip first two entries, "*new*" and "*current*"
984 rtable = lnext(lnext(pstate->p_rtable));
987 /* this should not happen */
989 elog(WARN, "cannot expand: null p_rtable");
992 * go through the range table and make a list of range table entries
993 * which we will expand.
997 RangeTblEntry *rte = lfirst(rt);
1000 * we only expand those specify in the from clause. (This will
1001 * also prevent us from using the wrong table in inserts: eg.
1002 * tenk2 in "insert into tenk2 select * from tenk1;")
1006 legit_rtable = lappend(legit_rtable, rte);
1009 foreach(rt, legit_rtable)
1011 RangeTblEntry *rte = lfirst(rt);
1012 List *temp = target;
1015 target = expandAll(pstate, rte->relname, rte->refname,
1016 &pstate->p_last_resno);
1019 while (temp != NIL && lnext(temp) != NIL)
1021 lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
1022 &pstate->p_last_resno);
1031 * if the name of the resulting column is not specified in the target
1032 * list, we have to guess.
1036 figureColname(Node *expr, Node *resval)
1038 switch (nodeTag(expr))
1041 return (char *) /* XXX */
1042 ((Aggreg *) expr)->aggname;
1044 if (((Expr *) expr)->opType == FUNC_EXPR)
1046 if (nodeTag(resval) == T_FuncCall)
1047 return ((FuncCall *) resval)->funcname;
1057 /*****************************************************************************
1061 *****************************************************************************/
1065 * generate a list of column names if not supplied or
1066 * test supplied column names to make sure they are in target table
1067 * (used exclusively for inserts)
1070 makeTargetNames(ParseState *pstate, List *cols)
1074 /* Generate ResTarget if not supplied */
1080 AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
1082 numcol = pstate->p_target_relation->rd_rel->relnatts;
1083 for (i = 0; i < numcol; i++)
1085 Ident *id = makeNode(Ident);
1087 id->name = palloc(NAMEDATALEN);
1088 strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN - 1);
1089 id->indirection = NIL;
1092 cols = tl = lcons(id, NIL);
1095 lnext(tl) = lcons(id, NIL);
1102 /* elog on failure */
1103 varattno(pstate->p_target_relation, ((Ident *) lfirst(tl))->name);
1109 * transformTargetList -
1110 * turns a list of ResTarget's into a list of TargetEntry's
1113 transformTargetList(ParseState *pstate, List *targetlist)
1115 List *p_target = NIL;
1116 List *tail_p_target = NIL;
1118 while (targetlist != NIL)
1120 ResTarget *res = (ResTarget *) lfirst(targetlist);
1121 TargetEntry *tent = makeNode(TargetEntry);
1123 switch (nodeTag(res->val))
1133 identname = ((Ident *) res->val)->name;
1134 handleTargetColname(pstate, &res->name, NULL, identname);
1137 * here we want to look for column names only, not
1142 * names (even though they can be stored in Ident
1146 expr = transformIdent(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1147 type_id = exprType(expr);
1148 type_len = tlen(get_id_type(type_id));
1149 resname = (res->name) ? res->name : identname;
1150 tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
1166 Node *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1168 handleTargetColname(pstate, &res->name, NULL, NULL);
1169 /* note indirection has not been transformed */
1170 if (pstate->p_is_insert && res->indirection != NIL)
1172 /* this is an array assignment */
1185 if (exprType(expr) != UNKNOWNOID ||
1187 elog(WARN, "yyparse: string constant expected");
1189 val = (char *) textout((struct varlena *)
1190 ((Const *) expr)->constvalue);
1191 str = save_str = (char *) palloc(strlen(val) + MAXDIM * 25 + 2);
1192 foreach(elt, res->indirection)
1194 A_Indices *aind = (A_Indices *) lfirst(elt);
1196 aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
1197 if (!IsA(aind->uidx, Const))
1199 "Array Index for Append should be a constant");
1200 uindx[i] = ((Const *) aind->uidx)->constvalue;
1201 if (aind->lidx != NULL)
1203 aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
1204 if (!IsA(aind->lidx, Const))
1206 "Array Index for Append should be a constant");
1207 lindx[i] = ((Const *) aind->lidx)->constvalue;
1213 if (lindx[i] > uindx[i])
1214 elog(WARN, "yyparse: lower index cannot be greater than upper index");
1215 sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
1219 sprintf(str, "=%s", val);
1220 rd = pstate->p_target_relation;
1222 resdomno = varattno(rd, res->name);
1223 ndims = att_attnelems(rd, resdomno);
1225 elog(WARN, "yyparse: array dimensions do not match");
1226 constval = makeNode(Value);
1227 constval->type = T_String;
1228 constval->val.str = save_str;
1229 tent = make_targetlist_expr(pstate, res->name,
1230 (Node *) make_const(constval),
1236 char *colname = res->name;
1238 /* this is not an array assignment */
1239 if (colname == NULL)
1243 * if you're wondering why this is here, look
1244 * at the yacc grammar for why a name can be
1247 colname = figureColname(expr, res->val);
1249 if (res->indirection)
1251 List *ilist = res->indirection;
1253 while (ilist != NIL)
1255 A_Indices *ind = lfirst(ilist);
1257 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1258 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1259 ilist = lnext(ilist);
1262 res->name = colname;
1263 tent = make_targetlist_expr(pstate, res->name, expr,
1272 Attr *att = (Attr *) res->val;
1277 List *attrs = att->attrs;
1280 * Target item is a single '*', expand all tables (eg.
1281 * SELECT * FROM emp)
1283 if (att->relname != NULL && !strcmp(att->relname, "*"))
1285 if (tail_p_target == NIL)
1286 p_target = tail_p_target = expandAllTables(pstate);
1288 lnext(tail_p_target) = expandAllTables(pstate);
1290 while (lnext(tail_p_target) != NIL)
1291 /* make sure we point to the last target entry */
1292 tail_p_target = lnext(tail_p_target);
1295 * skip rest of while loop
1297 targetlist = lnext(targetlist);
1302 * Target item is relation.*, expand the table (eg.
1303 * SELECT emp.*, dname FROM emp, dept)
1305 attrname = strVal(lfirst(att->attrs));
1306 if (att->attrs != NIL && !strcmp(attrname, "*"))
1310 * tail_p_target is the target list we're building
1311 * in the while loop. Make sure we fix it after
1312 * appending more nodes.
1314 if (tail_p_target == NIL)
1315 p_target = tail_p_target = expandAll(pstate, att->relname,
1316 att->relname, &pstate->p_last_resno);
1318 lnext(tail_p_target) =
1319 expandAll(pstate, att->relname, att->relname,
1320 &pstate->p_last_resno);
1321 while (lnext(tail_p_target) != NIL)
1322 /* make sure we point to the last target entry */
1323 tail_p_target = lnext(tail_p_target);
1326 * skip the rest of the while loop
1328 targetlist = lnext(targetlist);
1334 * Target item is fully specified: ie.
1335 * relation.attribute
1337 result = handleNestedDots(pstate, att, &pstate->p_last_resno);
1338 handleTargetColname(pstate, &res->name, att->relname, attrname);
1339 if (att->indirection != NIL)
1341 List *ilist = att->indirection;
1343 while (ilist != NIL)
1345 A_Indices *ind = lfirst(ilist);
1347 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1348 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1349 ilist = lnext(ilist);
1351 result = (Node *) make_array_ref(result, att->indirection);
1353 type_id = exprType(result);
1354 type_len = tlen(get_id_type(type_id));
1355 /* move to last entry */
1356 while (lnext(attrs) != NIL)
1357 attrs = lnext(attrs);
1358 resname = (res->name) ? res->name : strVal(lfirst(attrs));
1359 resnode = makeResdom((AttrNumber) pstate->p_last_resno++,
1366 tent->resdom = resnode;
1367 tent->expr = result;
1371 /* internal error */
1373 "internal error: do not know how to transform targetlist");
1377 if (p_target == NIL)
1379 p_target = tail_p_target = lcons(tent, NIL);
1383 lnext(tail_p_target) = lcons(tent, NIL);
1384 tail_p_target = lnext(tail_p_target);
1386 targetlist = lnext(targetlist);
1394 * make_targetlist_expr -
1395 * make a TargetEntry from an expression
1397 * arrayRef is a list of transformed A_Indices
1399 static TargetEntry *
1400 make_targetlist_expr(ParseState *pstate,
1416 elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
1418 type_id = exprType(expr);
1419 if (type_id == InvalidOid)
1424 type_len = tlen(get_id_type(type_id));
1426 /* I have no idea what the following does! */
1427 /* It appears to process target columns that will be receiving results */
1428 if (pstate->p_is_insert || pstate->p_is_update)
1432 * append or replace query -- append, replace work only on one
1433 * relation, so multiple occurence of same resdomno is bogus
1435 rd = pstate->p_target_relation;
1437 resdomno = varattno(rd, colname);
1438 attrisset = varisset(rd, colname);
1439 attrtype = att_typeid(rd, resdomno);
1440 if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
1441 attrtype = GetArrayElementType(attrtype);
1442 if (attrtype == BPCHAROID || attrtype == VARCHAROID)
1444 attrlen = rd->rd_att->attrs[resdomno - 1]->attlen;
1448 attrlen = tlen(get_id_type(attrtype));
1451 if (Input_is_string && Typecast_ok)
1455 if (type_id == typeid(type("unknown")))
1457 val = (Datum) textout((struct varlena *)
1458 ((Const) lnext(expr))->constvalue);
1462 val = ((Const) lnext(expr))->constvalue;
1466 lnext(expr) = makeConst(attrtype,
1479 (Datum) fmgr(typeid_get_retinfunc(attrtype),
1480 val, get_typelem(attrtype), -1),
1482 true /* Maybe correct-- 80% chance */ ,
1483 false, /* is not a set */
1487 else if ((Typecast_ok) && (attrtype != type_id))
1490 parser_typecast2(expr, get_id_type(attrtype));
1492 else if (attrtype != type_id)
1494 if ((attrtype == INT2OID) && (type_id == INT4OID))
1495 lfirst(expr) = lispInteger(INT2OID); /* handle CASHOID too */
1496 else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
1497 lfirst(expr) = lispInteger(FLOAT4OID);
1499 elog(WARN, "unequal type in tlist : %s \n", colname);
1502 Input_is_string = false;
1503 Input_is_integer = false;
1507 if (attrtype != type_id)
1509 if (IsA(expr, Const))
1511 /* try to cast the constant */
1512 if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
1514 /* updating a single item */
1515 Oid typelem = get_typelem(attrtype);
1517 expr = (Node *) parser_typecast2(expr,
1519 get_id_type(typelem),
1523 expr = (Node *) parser_typecast2(expr,
1525 get_id_type(attrtype),
1530 /* currently, we can't handle casting of expressions */
1531 elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
1533 get_id_typname(attrtype),
1534 get_id_typname(type_id));
1538 if (arrayRef != NIL)
1541 Attr *att = makeNode(Attr);
1542 List *ar = arrayRef;
1543 List *upperIndexpr = NIL;
1544 List *lowerIndexpr = NIL;
1546 att->relname = pstrdup(RelationGetRelationName(rd)->data);
1547 att->attrs = lcons(makeString(colname), NIL);
1548 target_expr = (Expr *) handleNestedDots(pstate, att,
1549 &pstate->p_last_resno);
1552 A_Indices *ind = lfirst(ar);
1554 if (lowerIndexpr || (!upperIndexpr && ind->lidx))
1558 * XXX assume all lowerIndexpr is non-null in this
1561 lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
1563 upperIndexpr = lappend(upperIndexpr, ind->uidx);
1567 expr = (Node *) make_array_set(target_expr,
1571 attrtype = att_typeid(rd, resdomno);
1572 attrlen = tlen(get_id_type(attrtype));
1577 resdomno = pstate->p_last_resno++;
1581 tent = makeNode(TargetEntry);
1583 resnode = makeResdom((AttrNumber) resdomno,
1591 tent->resdom = resnode;
1598 /*****************************************************************************
1602 *****************************************************************************/
1605 * transformWhereClause -
1606 * transforms the qualification and make sure it is of type Boolean
1610 transformWhereClause(ParseState *pstate, Node *a_expr)
1615 return (Node *) NULL; /* no qualifiers */
1617 inWhereClause = true;
1618 qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
1619 inWhereClause = false;
1620 if (exprType(qual) != BOOLOID)
1623 "where clause must return type bool, not %s",
1624 tname(get_id_type(exprType(qual))));
1629 /*****************************************************************************
1633 *****************************************************************************/
1636 * find_targetlist_entry -
1637 * returns the Resdom in the target list matching the specified varname
1641 static TargetEntry *
1642 find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
1645 int real_rtable_pos = 0,
1647 TargetEntry *target_result = NULL;
1649 if (sortgroupby->range)
1650 real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
1651 sortgroupby->range);
1655 TargetEntry *target = (TargetEntry *) lfirst(i);
1656 Resdom *resnode = target->resdom;
1657 Var *var = (Var *) target->expr;
1658 char *resname = resnode->resname;
1659 int test_rtable_pos = var->varno;
1662 printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
1663 (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno);
1666 if (!sortgroupby->name)
1668 if (sortgroupby->resno == ++target_pos)
1670 target_result = target;
1676 if (!strcmp(resname, sortgroupby->name))
1678 if (sortgroupby->range)
1680 if (real_rtable_pos == test_rtable_pos)
1682 if (target_result != NULL)
1683 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1685 target_result = target;
1690 if (target_result != NULL)
1691 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1693 target_result = target;
1698 return target_result;
1702 any_ordering_op(int restype)
1707 order_op = oper("<", restype, restype, false);
1708 order_opid = oprid(order_op);
1714 * transformGroupClause -
1715 * transform a Group By clause
1719 transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
1724 while (grouplist != NIL)
1726 GroupClause *grpcl = makeNode(GroupClause);
1727 TargetEntry *restarget;
1730 restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
1732 if (restarget == NULL)
1733 elog(WARN, "The field being grouped by must appear in the target list");
1735 grpcl->entry = restarget;
1736 resdom = restarget->resdom;
1737 grpcl->grpOpoid = oprid(oper("<",
1739 resdom->restype, false));
1741 gl = glist = lcons(grpcl, NIL);
1744 lnext(gl) = lcons(grpcl, NIL);
1747 grouplist = lnext(grouplist);
1754 * transformSortClause -
1755 * transform an Order By clause
1759 transformSortClause(ParseState *pstate,
1760 List *orderlist, List *targetlist,
1763 List *sortlist = NIL;
1767 while (orderlist != NIL)
1769 SortGroupBy *sortby = lfirst(orderlist);
1770 SortClause *sortcl = makeNode(SortClause);
1771 TargetEntry *restarget;
1774 restarget = find_targetlist_entry(pstate, sortby, targetlist);
1775 if (restarget == NULL)
1776 elog(WARN, "The field being ordered by must appear in the target list");
1778 sortcl->resdom = resdom = restarget->resdom;
1779 sortcl->opoid = oprid(oper(sortby->useOp,
1781 resdom->restype, false));
1782 if (sortlist == NIL)
1784 s = sortlist = lcons(sortcl, NIL);
1788 lnext(s) = lcons(sortcl, NIL);
1791 orderlist = lnext(orderlist);
1796 if (uniqueFlag[0] == '*')
1800 * concatenate all elements from target list that are not
1801 * already in the sortby list
1803 foreach(i, targetlist)
1805 TargetEntry *tlelt = (TargetEntry *) lfirst(i);
1810 SortClause *sortcl = lfirst(s);
1812 if (sortcl->resdom == tlelt->resdom)
1818 /* not a member of the sortclauses yet */
1819 SortClause *sortcl = makeNode(SortClause);
1821 sortcl->resdom = tlelt->resdom;
1822 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1824 sortlist = lappend(sortlist, sortcl);
1830 TargetEntry *tlelt = NULL;
1831 char *uniqueAttrName = uniqueFlag;
1833 /* only create sort clause with the specified unique attribute */
1834 foreach(i, targetlist)
1836 tlelt = (TargetEntry *) lfirst(i);
1837 if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
1842 elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
1845 foreach(s, sortlist)
1847 SortClause *sortcl = lfirst(s);
1849 if (sortcl->resdom == tlelt->resdom)
1854 /* not a member of the sortclauses yet */
1855 SortClause *sortcl = makeNode(SortClause);
1857 sortcl->resdom = tlelt->resdom;
1858 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1860 sortlist = lappend(sortlist, sortcl);
1870 ** HandleNestedDots --
1871 ** Given a nested dot expression (i.e. (relation func ... attr), build up
1872 ** a tree with of Iter and Func nodes.
1875 handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
1878 Node *retval = NULL;
1880 if (attr->paramNo != NULL)
1882 Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
1885 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1891 Ident *ident = makeNode(Ident);
1893 ident->name = attr->relname;
1894 ident->isRel = TRUE;
1896 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1901 foreach(mutator_iter, lnext(attr->attrs))
1903 retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)),
1912 ** make_arguments --
1913 ** Given the number and types of arguments to a function, and the
1914 ** actual arguments and argument types, do the necessary typecasting.
1917 make_arguments(int nargs,
1920 Oid *function_typeids)
1924 * there are two ways an input typeid can differ from a function
1925 * typeid : either the input type inherits the function type, so no
1926 * typecasting is necessary, or the input type can be typecast into
1927 * the function type. right now, we only typecast unknowns, and that
1928 * is all we check for.
1931 List *current_fargs;
1934 for (i = 0, current_fargs = fargs;
1936 i++, current_fargs = lnext(current_fargs))
1939 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
1941 lfirst(current_fargs) =
1942 parser_typecast2(lfirst(current_fargs),
1944 get_id_type(function_typeids[i]),
1952 ** Build a tlist that says which attribute to project to.
1953 ** This routine is called by ParseFunc() to set up a target list
1954 ** on a tuple parameter or return value. Due to a bug in 4.0,
1955 ** it's not possible to refer to system attributes in this case.
1958 setup_tlist(char *attname, Oid relid)
1966 attno = get_attnum(relid, attname);
1968 elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
1970 typeid = find_atttype(relid, attname);
1971 resnode = makeResdom(1,
1973 tlen(get_id_type(typeid)),
1974 get_attname(relid, attno),
1978 varnode = makeVar(-1, attno, typeid, -1, attno);
1980 tle = makeNode(TargetEntry);
1981 tle->resdom = resnode;
1982 tle->expr = (Node *) varnode;
1983 return (lcons(tle, NIL));
1987 ** setup_base_tlist --
1988 ** Build a tlist that extracts a base type from the tuple
1989 ** returned by the executor.
1992 setup_base_tlist(Oid typeid)
1998 resnode = makeResdom(1,
2000 tlen(get_id_type(typeid)),
2005 varnode = makeVar(-1, 1, typeid, -1, 1);
2006 tle = makeNode(TargetEntry);
2007 tle->resdom = resnode;
2008 tle->expr = (Node *) varnode;
2010 return (lcons(tle, NIL));
2014 * ParseComplexProjection -
2015 * handles function calls with a single argument that is of complex type.
2016 * This routine returns NULL if it can't handle the projection (eg. sets).
2019 ParseComplexProjection(ParseState *pstate,
2031 switch (nodeTag(first_arg))
2038 iter = (Iter *) first_arg;
2039 func = (Func *) ((Expr *) iter->iterexpr)->oper;
2040 argtype = funcid_get_rettype(func->funcid);
2041 argrelid = typeid_get_relid(argtype);
2043 ((attnum = get_attnum(argrelid, funcname))
2044 != InvalidAttrNumber))
2048 * the argument is a function returning a tuple, so
2049 * funcname may be a projection
2052 /* add a tlist to the func node and return the Iter */
2053 rd = heap_openr(tname(get_id_type(argtype)));
2054 if (RelationIsValid(rd))
2056 relid = RelationGetRelationId(rd);
2057 relname = RelationGetRelationName(rd);
2060 if (RelationIsValid(rd))
2063 setup_tlist(funcname, argrelid);
2064 iter->itertype = att_typeid(rd, attnum);
2065 return ((Node *) iter);
2070 "Function %s has bad returntype %d",
2085 * The argument is a set, so this is either a projection
2086 * or a function call on this set.
2093 Expr *expr = (Expr *) first_arg;
2096 if (expr->opType != FUNC_EXPR)
2099 funcnode = (Func *) expr->oper;
2100 argtype = funcid_get_rettype(funcnode->funcid);
2101 argrelid = typeid_get_relid(argtype);
2104 * the argument is a function returning a tuple, so
2105 * funcname may be a projection
2108 (attnum = get_attnum(argrelid, funcname))
2109 != InvalidAttrNumber)
2112 /* add a tlist to the func node */
2113 rd = heap_openr(tname(get_id_type(argtype)));
2114 if (RelationIsValid(rd))
2116 relid = RelationGetRelationId(rd);
2117 relname = RelationGetRelationName(rd);
2120 if (RelationIsValid(rd))
2124 funcnode->func_tlist =
2125 setup_tlist(funcname, argrelid);
2126 funcnode->functype = att_typeid(rd, attnum);
2128 newexpr = makeNode(Expr);
2129 newexpr->typeOid = funcnode->functype;
2130 newexpr->opType = FUNC_EXPR;
2131 newexpr->oper = (Node *) funcnode;
2132 newexpr->args = lcons(first_arg, NIL);
2134 return ((Node *) newexpr);
2139 elog(WARN, "Function %s has bad returntype %d",
2145 Param *param = (Param *) first_arg;
2148 * If the Param is a complex type, this could be a
2151 rd = heap_openr(tname(get_id_type(param->paramtype)));
2152 if (RelationIsValid(rd))
2154 relid = RelationGetRelationId(rd);
2155 relname = RelationGetRelationName(rd);
2158 if (RelationIsValid(rd) &&
2159 (attnum = get_attnum(relid, funcname))
2160 != InvalidAttrNumber)
2163 param->paramtype = att_typeid(rd, attnum);
2164 param->param_tlist = setup_tlist(funcname, relid);
2165 return ((Node *) param);
2177 ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
2179 Oid rettype = (Oid) 0;
2180 Oid argrelid = (Oid) 0;
2181 Oid funcid = (Oid) 0;
2183 Node *first_arg = NULL;
2184 char *relname = NULL;
2185 char *refname = NULL;
2191 Oid *true_oid_array;
2195 bool attisset = false;
2201 first_arg = lfirst(fargs);
2202 if (first_arg == NULL)
2203 elog(WARN, "function %s does not allow NULL input", funcname);
2207 * * check for projection methods: if function takes one argument, and *
2208 * that argument is a relation, param, or PQ function returning a
2209 * complex * type, then the function could be a projection.
2211 if (length(fargs) == 1)
2214 if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
2217 Ident *ident = (Ident *) first_arg;
2220 * first arg is a relation. This could be a projection.
2222 refname = ident->name;
2224 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2226 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
2228 relname = rte->relname;
2232 * If the attr isn't a set, just make a var for it. If it is
2233 * a set, treat it like a function and drop through.
2235 if (get_attnum(relid, funcname) != InvalidAttrNumber)
2240 ((Node *) make_var(pstate,
2247 /* drop through - attr is a set */
2251 else if (ISCOMPLEX(exprType(first_arg)))
2255 * Attempt to handle projection of a complex argument. If
2256 * ParseComplexProjection can't handle the projection, we have
2259 retval = ParseComplexProjection(pstate,
2265 toid = exprType(first_arg);
2266 rd = heap_openr(tname(get_id_type(toid)));
2267 if (RelationIsValid(rd))
2269 relname = RelationGetRelationName(rd)->data;
2274 "Type %s is not a relation type",
2275 tname(get_id_type(toid)));
2276 argrelid = typeid_get_relid(toid);
2279 * A projection contains either an attribute name or the
2282 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
2283 && strcmp(funcname, "*"))
2285 elog(WARN, "Functions on sets are not yet supported");
2296 * Parsing aggregates.
2301 * the aggregate count is a special case, ignore its base
2302 * type. Treat it as zero
2304 if (strcmp(funcname, "count") == 0)
2307 basetype = exprType(lfirst(fargs));
2308 if (SearchSysCacheTuple(AGGNAME,
2309 PointerGetDatum(funcname),
2310 ObjectIdGetDatum(basetype),
2313 Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
2315 AddAggToParseState(pstate, aggreg);
2316 return (Node *) aggreg;
2323 * * If we dropped through to here it's really a function (or a set,
2324 * which * is implemented as a function.) * extract arg type info and
2325 * transform relation name arguments into * varnodes of the
2328 memset(&oid_array[0], 0, 8 * sizeof(Oid));
2335 Node *pair = lfirst(i);
2337 if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
2343 refname = ((Ident *) pair)->name;
2345 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2347 rte = addRangeTableEntry(pstate, refname, refname,
2348 FALSE, FALSE, NULL);
2349 relname = rte->relname;
2351 vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname);
2354 * for func(relname), the param to the function is the tuple
2355 * under consideration. we build a special VarNode to reflect
2356 * this -- it has varno set to the correct range table entry,
2357 * but has varattno == 0 to signal that the whole tuple is the
2360 toid = typeid(type(relname));
2361 /* replace it in the arg list */
2363 makeVar(vnum, 0, toid, vnum, 0);
2366 { /* set functions don't have parameters */
2369 * any functiona args which are typed "unknown", but aren't
2370 * constants, we don't know what to do with, because we can't
2373 if (exprType(pair) == UNKNOWNOID &&
2376 elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
2379 toid = exprType(pair);
2382 oid_array[nargs++] = toid;
2386 * func_get_detail looks up the function in the catalogs, does
2387 * disambiguation for polymorphic functions, handles inheritance, and
2388 * returns the funcid and type and set or singleton status of the
2389 * function's return value. it also returns the true argument types
2390 * to the function. if func_get_detail returns true, the function
2391 * exists. otherwise, there was an error.
2394 { /* we know all of these fields already */
2397 * We create a funcnode with a placeholder function SetEval.
2398 * SetEval() never actually gets executed. When the function
2399 * evaluation routines see it, they use the funcid projected out
2400 * from the relation as the actual function to call. Example:
2401 * retrieve (emp.mgr.name) The plan for this will scan the emp
2402 * relation, projecting out the mgr attribute, which is a funcid.
2403 * This function is then called (instead of SetEval) and "name" is
2404 * projected from its result.
2406 funcid = SetEvalRegProcedure;
2409 true_oid_array = oid_array;
2414 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
2415 &rettype, &retset, &true_oid_array);
2419 elog(WARN, "no such attribute or function %s", funcname);
2422 funcnode = makeNode(Func);
2423 funcnode->funcid = funcid;
2424 funcnode->functype = rettype;
2425 funcnode->funcisindex = false;
2426 funcnode->funcsize = 0;
2427 funcnode->func_fcache = NULL;
2428 funcnode->func_tlist = NIL;
2429 funcnode->func_planlist = NIL;
2431 /* perform the necessary typecasting */
2432 make_arguments(nargs, fargs, oid_array, true_oid_array);
2435 * for functions returning base types, we want to project out the
2436 * return value. set up a target list to do that. the executor will
2437 * ignore these for c functions, and do the right thing for postquel
2441 if (typeid_get_relid(rettype) == InvalidOid)
2442 funcnode->func_tlist = setup_base_tlist(rettype);
2445 * For sets, we want to make a targetlist to project out this
2446 * attribute of the set tuples.
2450 if (!strcmp(funcname, "*"))
2452 funcnode->func_tlist =
2453 expandAll(pstate, relname, refname, curr_resno);
2457 funcnode->func_tlist = setup_tlist(funcname, argrelid);
2458 rettype = find_atttype(argrelid, funcname);
2463 * Sequence handling.
2465 if (funcid == SeqNextValueRegProcedure ||
2466 funcid == SeqCurrValueRegProcedure)
2471 int32 aclcheck_result = -1;
2472 extern text *lower (text *string);
2474 Assert(length(fargs) == 1);
2475 seq = (Const *) lfirst(fargs);
2476 if (!IsA((Node *) seq, Const))
2477 elog(WARN, "%s: only constant sequence names are acceptable", funcname);
2478 seqname = lower ((text*)DatumGetPointer(seq->constvalue));
2479 pfree (DatumGetPointer(seq->constvalue));
2480 seq->constvalue = PointerGetDatum (seqname);
2481 seqrel = textout(seqname);
2483 if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
2484 ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)))
2486 elog(WARN, "%s.%s: %s",
2487 seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
2491 if (funcid == SeqNextValueRegProcedure && inWhereClause)
2492 elog(WARN, "nextval of a sequence in WHERE disallowed");
2495 expr = makeNode(Expr);
2496 expr->typeOid = rettype;
2497 expr->opType = FUNC_EXPR;
2498 expr->oper = (Node *) funcnode;
2500 retval = (Node *) expr;
2503 * if the function returns a set of values, then we need to iterate
2504 * over all the returned values in the executor, so we stick an iter
2505 * node here. if it returns a singleton, then we don't need the iter
2511 Iter *iter = makeNode(Iter);
2513 iter->itertype = rettype;
2514 iter->iterexpr = retval;
2515 retval = (Node *) iter;
2521 /*****************************************************************************
2523 *****************************************************************************/
2526 * AddAggToParseState -
2527 * add the aggregate to the list of unique aggregates in pstate.
2529 * SIDE EFFECT: aggno in target list entry will be modified
2532 AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
2538 * see if we have the aggregate already (we only need to record the
2542 foreach(ag, pstate->p_aggs)
2544 Aggreg *a = lfirst(ag);
2546 if (!strcmp(a->aggname, aggreg->aggname) &&
2547 equal(a->target, aggreg->target))
2550 /* fill in the aggno and we're done */
2557 /* not found, new aggregate */
2560 pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
2565 * finalizeAggregates -
2566 * fill in qry_aggs from pstate. Also checks to make sure that aggregates
2567 * are used in the proper place.
2570 finalizeAggregates(ParseState *pstate, Query *qry)
2575 parseCheckAggregates(pstate, qry);
2577 qry->qry_numAgg = pstate->p_numAgg;
2579 (Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
2581 foreach(l, pstate->p_aggs)
2582 qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
2586 * contain_agg_clause--
2587 * Recursively find aggreg nodes from a clause.
2589 * Returns true if any aggregate found.
2592 contain_agg_clause(Node *clause)
2596 else if (IsA(clause, Aggreg))
2598 else if (IsA(clause, Iter))
2599 return contain_agg_clause(((Iter *) clause)->iterexpr);
2600 else if (single_node(clause))
2602 else if (or_clause(clause))
2606 foreach(temp, ((Expr *) clause)->args)
2607 if (contain_agg_clause(lfirst(temp)))
2611 else if (is_funcclause(clause))
2615 foreach(temp, ((Expr *) clause)->args)
2616 if (contain_agg_clause(lfirst(temp)))
2620 else if (IsA(clause, ArrayRef))
2624 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
2625 if (contain_agg_clause(lfirst(temp)))
2627 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
2628 if (contain_agg_clause(lfirst(temp)))
2630 if (contain_agg_clause(((ArrayRef *) clause)->refexpr))
2632 if (contain_agg_clause(((ArrayRef *) clause)->refassgnexpr))
2636 else if (not_clause(clause))
2637 return contain_agg_clause((Node *) get_notclausearg((Expr *) clause));
2638 else if (is_opclause(clause))
2639 return (contain_agg_clause((Node *) get_leftop((Expr *) clause)) ||
2640 contain_agg_clause((Node *) get_rightop((Expr *) clause)));
2646 * exprIsAggOrGroupCol -
2647 * returns true if the expression does not contain non-group columns.
2650 exprIsAggOrGroupCol(Node *expr, List *groupClause)
2654 if (expr == NULL || IsA(expr, Const) ||
2655 IsA(expr, Param) ||IsA(expr, Aggreg))
2658 foreach(gl, groupClause)
2660 GroupClause *grpcl = lfirst(gl);
2662 if (equal(expr, grpcl->entry->expr))
2666 if (IsA(expr, Expr))
2670 foreach(temp, ((Expr *) expr)->args)
2671 if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2680 * tleIsAggOrGroupCol -
2681 * returns true if the TargetEntry is Agg or GroupCol.
2684 tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
2686 Node *expr = tle->expr;
2689 if (expr == NULL || IsA(expr, Const) ||IsA(expr, Param))
2692 foreach(gl, groupClause)
2694 GroupClause *grpcl = lfirst(gl);
2696 if (tle->resdom->resno == grpcl->entry->resdom->resno)
2698 if (contain_agg_clause((Node *) expr))
2699 elog(WARN, "parser: aggregates not allowed in GROUP BY clause");
2704 if (IsA(expr, Aggreg))
2707 if (IsA(expr, Expr))
2711 foreach(temp, ((Expr *) expr)->args)
2712 if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2721 * parseCheckAggregates -
2722 * this should really be done earlier but the current grammar
2723 * cannot differentiate functions from aggregates. So we have do check
2724 * here when the target list and the qualifications are finalized.
2727 parseCheckAggregates(ParseState *pstate, Query *qry)
2731 Assert(pstate->p_numAgg > 0);
2734 * aggregates never appear in WHERE clauses. (we have to check where
2735 * clause first because if there is an aggregate, the check for
2736 * non-group column in target list may fail.)
2738 if (contain_agg_clause(qry->qual))
2739 elog(WARN, "parser: aggregates not allowed in WHERE clause");
2742 * the target list can only contain aggregates, group columns and
2743 * functions thereof.
2745 foreach(tl, qry->targetList)
2747 TargetEntry *tle = lfirst(tl);
2749 if (!tleIsAggOrGroupCol(tle, qry->groupClause))
2751 "parser: illegal use of aggregates or non-group column in target list");
2755 * the expression specified in the HAVING clause has the same
2756 * restriction as those in the target list.
2759 * Need to change here when we get HAVING works. Currently
2760 * qry->havingQual is NULL. - vadim 04/05/97
2761 if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
2763 "parser: illegal use of aggregates or non-group column in HAVING clause");