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.46 1997/10/16 06:58:38 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 */
308 qry->commandType = CMD_INSERT;
309 pstate->p_is_insert = true;
311 /* set up a range table */
312 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
314 qry->uniqueFlag = NULL;
316 /* fix the target list */
317 icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
319 qry->targetList = transformTargetList(pstate, stmt->targetList);
321 /* DEFAULT handling */
322 if (length(qry->targetList) < pstate->p_target_relation->rd_att->natts &&
323 pstate->p_target_relation->rd_att->constr &&
324 pstate->p_target_relation->rd_att->constr->num_defval > 0)
326 AttributeTupleForm *att = pstate->p_target_relation->rd_att->attrs;
327 AttrDefault *defval = pstate->p_target_relation->rd_att->constr->defval;
328 int ndef = pstate->p_target_relation->rd_att->constr->num_defval;
331 * if stmt->cols == NIL then makeTargetNames returns list of all
332 * attrs: have to shorter icolumns list...
334 if (stmt->cols == NIL)
337 int i = length(qry->targetList);
339 foreach (extrl, icolumns)
344 freeList (lnext(extrl));
354 foreach (tl, icolumns)
356 id = (Ident *) lfirst(tl);
357 if (!namestrcmp(&(att[defval[ndef].adnum - 1]->attname), id->name))
360 if (tl != NIL) /* something given for this attr */
363 * Nothing given for this attr with DEFAULT expr, so
364 * add new TargetEntry to qry->targetList.
365 * Note, that we set resno to defval[ndef].adnum:
366 * it's what transformTargetList()->make_targetlist_expr()
367 * does for INSERT ... SELECT. But for INSERT ... VALUES
368 * pstate->p_last_resno is used. It doesn't matter for
369 * "normal" using (planner creates proper target list
370 * in preptlist.c), but may break RULEs in some way.
371 * It seems better to create proper target list here...
373 te = makeNode(TargetEntry);
374 te->resdom = makeResdom(defval[ndef].adnum,
375 att[defval[ndef].adnum - 1]->atttypid,
376 att[defval[ndef].adnum - 1]->attlen,
377 pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
380 te->expr = (Node *) stringToNode(defval[ndef].adbin);
381 qry->targetList = lappend (qry->targetList, te);
385 /* fix where clause */
386 qry->qual = transformWhereClause(pstate, stmt->whereClause);
388 /* now the range table will not change */
389 qry->rtable = pstate->p_rtable;
390 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
392 if (pstate->p_numAgg > 0)
393 finalizeAggregates(pstate, qry);
395 return (Query *) qry;
399 * transformIndexStmt -
400 * transforms the qualification of the index statement
403 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
408 q->commandType = CMD_UTILITY;
410 /* take care of the where clause */
411 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
412 stmt->rangetable = pstate->p_rtable;
414 q->utilityStmt = (Node *) stmt;
420 * transformExtendStmt -
421 * transform the qualifications of the Extend Index Statement
425 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
430 q->commandType = CMD_UTILITY;
432 /* take care of the where clause */
433 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
434 stmt->rangetable = pstate->p_rtable;
436 q->utilityStmt = (Node *) stmt;
441 * transformRuleStmt -
442 * transform a Create Rule Statement. The actions is a list of parse
443 * trees which is transformed into a list of query trees.
446 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
452 q->commandType = CMD_UTILITY;
454 actions = stmt->actions;
457 * transform each statment, like parse_analyze()
459 while (actions != NIL)
463 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
466 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
468 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
471 pstate->p_last_resno = 1;
472 pstate->p_is_rule = true; /* for expand all */
473 pstate->p_numAgg = 0;
474 pstate->p_aggs = NULL;
476 lfirst(actions) = transformStmt(pstate, lfirst(actions));
477 actions = lnext(actions);
480 /* take care of the where clause */
481 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
483 q->utilityStmt = (Node *) stmt;
489 * transformSelectStmt -
490 * transforms a Select Statement
494 transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
496 Query *qry = makeNode(Query);
498 qry->commandType = CMD_SELECT;
500 /* set up a range table */
501 makeRangeTable(pstate, NULL, stmt->fromClause);
503 qry->uniqueFlag = stmt->unique;
505 qry->into = stmt->into;
506 qry->isPortal = FALSE;
508 /* fix the target list */
509 qry->targetList = transformTargetList(pstate, stmt->targetList);
511 /* fix where clause */
512 qry->qual = transformWhereClause(pstate, stmt->whereClause);
514 /* check subselect clause */
515 if (stmt->selectClause)
516 elog(NOTICE, "UNION not yet supported; using first SELECT only", NULL);
518 /* check subselect clause */
519 if (stmt->havingClause)
520 elog(NOTICE, "HAVING not yet supported; ignore clause", NULL);
522 /* fix order clause */
523 qry->sortClause = transformSortClause(pstate,
528 /* fix group by clause */
529 qry->groupClause = transformGroupClause(pstate,
532 qry->rtable = pstate->p_rtable;
534 if (pstate->p_numAgg > 0)
535 finalizeAggregates(pstate, qry);
537 return (Query *) qry;
541 * transformUpdateStmt -
542 * transforms an update statement
546 transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt)
548 Query *qry = makeNode(Query);
550 qry->commandType = CMD_UPDATE;
551 pstate->p_is_update = true;
554 * the FROM clause is non-standard SQL syntax. We used to be able to
555 * do this with REPLACE in POSTQUEL so we keep the feature.
557 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
559 /* fix the target list */
560 qry->targetList = transformTargetList(pstate, stmt->targetList);
562 /* fix where clause */
563 qry->qual = transformWhereClause(pstate, stmt->whereClause);
565 qry->rtable = pstate->p_rtable;
566 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
568 /* make sure we don't have aggregates in the where clause */
569 if (pstate->p_numAgg > 0)
570 parseCheckAggregates(pstate, qry);
572 return (Query *) qry;
576 * transformCursorStmt -
577 * transform a Create Cursor Statement
581 transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
583 Query *qry = makeNode(Query);
586 * in the old days, a cursor statement is a 'retrieve into portal'; If
587 * you change the following, make sure you also go through the code in
588 * various places that tests the kind of operation.
590 qry->commandType = CMD_SELECT;
592 /* set up a range table */
593 makeRangeTable(pstate, NULL, stmt->fromClause);
595 qry->uniqueFlag = stmt->unique;
597 qry->into = stmt->portalname;
598 qry->isPortal = TRUE;
599 qry->isBinary = stmt->binary; /* internal portal */
601 /* fix the target list */
602 qry->targetList = transformTargetList(pstate, stmt->targetList);
604 /* fix where clause */
605 qry->qual = transformWhereClause(pstate, stmt->whereClause);
607 /* fix order clause */
608 qry->sortClause = transformSortClause(pstate,
612 /* fix group by clause */
613 qry->groupClause = transformGroupClause(pstate,
617 qry->rtable = pstate->p_rtable;
619 if (pstate->p_numAgg > 0)
620 finalizeAggregates(pstate, qry);
622 return (Query *) qry;
625 /*****************************************************************************
627 * Transform Exprs, Aggs, etc.
629 *****************************************************************************/
633 * analyze and transform expressions. Type checking and type casting is
634 * done here. The optimizer and the executor cannot handle the original
635 * (raw) expressions collected by the parse tree. Hence the transformation
639 transformExpr(ParseState *pstate, Node *expr, int precedence)
646 switch (nodeTag(expr))
650 Attr *att = (Attr *) expr;
653 /* what if att.attrs == "*"?? */
654 temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
655 if (att->indirection != NIL)
657 List *idx = att->indirection;
661 A_Indices *ai = (A_Indices *) lfirst(idx);
665 uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
666 if (exprType(uexpr) != INT4OID)
667 elog(WARN, "array index expressions must be int4's");
668 if (ai->lidx != NULL)
670 lexpr = transformExpr(pstate, ai->lidx, precedence);
671 if (exprType(lexpr) != INT4OID)
672 elog(WARN, "array index expressions must be int4's");
676 if (ai->lidx != NULL)
683 * note we reuse the list of indices, make sure we
684 * don't free them! Otherwise, make a new list
689 result = (Node *) make_array_ref(temp, att->indirection);
699 A_Const *con = (A_Const *) expr;
700 Value *val = &con->val;
702 if (con->typename != NULL)
704 result = parser_typecast(val, con->typename, -1);
708 result = (Node *) make_const(val);
714 ParamNo *pno = (ParamNo *) expr;
719 paramno = pno->number;
720 toid = param_type(paramno);
721 if (!OidIsValid(toid))
723 elog(WARN, "Parameter '$%d' is out of range",
726 param = makeNode(Param);
727 param->paramkind = PARAM_NUM;
728 param->paramid = (AttrNumber) paramno;
729 param->paramname = "<unnamed>";
730 param->paramtype = (Oid) toid;
731 param->param_tlist = (List *) NULL;
733 result = (Node *) param;
738 A_Expr *a = (A_Expr *) expr;
744 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
745 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
747 result = (Node *) make_op(a->opname, lexpr, rexpr);
752 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
754 result = ParseFunc(pstate,
755 "nullvalue", lcons(lexpr, NIL),
756 &pstate->p_last_resno);
761 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
763 result = ParseFunc(pstate,
764 "nonnullvalue", lcons(lexpr, NIL),
765 &pstate->p_last_resno);
770 Expr *expr = makeNode(Expr);
771 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
772 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
774 if (exprType(lexpr) != BOOLOID)
776 "left-hand side of AND is type '%s', not bool",
777 tname(get_id_type(exprType(lexpr))));
778 if (exprType(rexpr) != BOOLOID)
780 "right-hand side of AND is type '%s', not bool",
781 tname(get_id_type(exprType(rexpr))));
782 expr->typeOid = BOOLOID;
783 expr->opType = AND_EXPR;
784 expr->args = makeList(lexpr, rexpr, -1);
785 result = (Node *) expr;
790 Expr *expr = makeNode(Expr);
791 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
792 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
794 if (exprType(lexpr) != BOOLOID)
796 "left-hand side of OR is type '%s', not bool",
797 tname(get_id_type(exprType(lexpr))));
798 if (exprType(rexpr) != BOOLOID)
800 "right-hand side of OR is type '%s', not bool",
801 tname(get_id_type(exprType(rexpr))));
802 expr->typeOid = BOOLOID;
803 expr->opType = OR_EXPR;
804 expr->args = makeList(lexpr, rexpr, -1);
805 result = (Node *) expr;
810 Expr *expr = makeNode(Expr);
811 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
813 if (exprType(rexpr) != BOOLOID)
815 "argument to NOT is type '%s', not bool",
816 tname(get_id_type(exprType(rexpr))));
817 expr->typeOid = BOOLOID;
818 expr->opType = NOT_EXPR;
819 expr->args = makeList(rexpr, -1);
820 result = (Node *) expr;
830 * look for a column name or a relation name (the default
833 result = transformIdent(pstate, expr, precedence);
838 FuncCall *fn = (FuncCall *) expr;
841 /* transform the list of arguments */
842 foreach(args, fn->args)
843 lfirst(args) = transformExpr(pstate, (Node *) lfirst(args), precedence);
844 result = ParseFunc(pstate,
845 fn->funcname, fn->args, &pstate->p_last_resno);
849 /* should not reach here */
850 elog(WARN, "transformExpr: does not know how to transform %d\n",
859 transformIdent(ParseState *pstate, Node *expr, int precedence)
861 Ident *ident = (Ident *) expr;
867 column_result = relation_result = result = 0;
868 /* try to find the ident as a column */
869 if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL)
871 Attr *att = makeNode(Attr);
873 att->relname = rte->refname;
874 att->attrs = lcons(makeString(ident->name), NIL);
876 (Node *) handleNestedDots(pstate, att, &pstate->p_last_resno);
879 /* try to find the ident as a relation */
880 if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL)
883 relation_result = (Node *) ident;
886 /* choose the right result based on the precedence */
887 if (precedence == EXPR_COLUMN_FIRST)
890 result = column_result;
892 result = relation_result;
897 result = relation_result;
899 result = column_result;
903 elog(WARN, "attribute \"%s\" not found", ident->name);
908 /*****************************************************************************
912 *****************************************************************************/
916 * turns the table references specified in the from-clause into a
917 * range table. The range table may grow as we transform the expressions
918 * in the target list. (Note that this happens because in POSTQUEL, we
919 * allow references to relations not specified in the from-clause. We
920 * also allow that in our POST-SQL)
924 parseFromClause(ParseState *pstate, List *frmList)
930 RangeVar *r = lfirst(fl);
931 RelExpr *baserel = r->relExpr;
932 char *relname = baserel->relname;
933 char *refname = r->name;
940 * marks this entry to indicate it comes from the FROM clause. In
941 * SQL, the target list can only refer to range variables
942 * specified in the from clause but we follow the more powerful
943 * POSTQUEL semantics and automatically generate the range
944 * variable if not specified. However there are times we need to
945 * know whether the entries are legitimate.
947 * eg. select * from foo f where f.x = 1; will generate wrong answer
948 * if we expand * to foo.x.
950 rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
957 * make a range table with the specified relation (optional) and the
961 makeRangeTable(ParseState *pstate, char *relname, List *frmList)
965 parseFromClause(pstate, frmList);
970 if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
971 rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
973 rte = refnameRangeTableEntry(pstate->p_rtable, relname);
975 pstate->p_target_rangetblentry = rte;
976 Assert(pstate->p_target_relation == NULL);
977 pstate->p_target_relation = heap_open(rte->relid);
978 Assert(pstate->p_target_relation != NULL);
979 /* will close relation later */
984 * returns the Oid of the type of the expression. (Used for typechecking.)
991 switch (nodeTag(expr))
994 type = ((Func *) expr)->functype;
997 type = ((Iter *) expr)->itertype;
1000 type = ((Var *) expr)->vartype;
1003 type = ((Expr *) expr)->typeOid;
1006 type = ((Const *) expr)->consttype;
1009 type = ((ArrayRef *) expr)->refelemtype;
1012 type = ((Aggreg *) expr)->aggtype;
1015 type = ((Param *) expr)->paramtype;
1018 /* is this right? */
1022 elog(WARN, "exprType: don't know how to get type for %d node",
1031 * turns '*' (in the target list) into a list of attributes (of all
1032 * relations in the range table)
1035 expandAllTables(ParseState *pstate)
1038 List *legit_rtable = NIL;
1042 rtable = pstate->p_rtable;
1043 if (pstate->p_is_rule)
1047 * skip first two entries, "*new*" and "*current*"
1049 rtable = lnext(lnext(pstate->p_rtable));
1052 /* this should not happen */
1054 elog(WARN, "cannot expand: null p_rtable");
1057 * go through the range table and make a list of range table entries
1058 * which we will expand.
1062 RangeTblEntry *rte = lfirst(rt);
1065 * we only expand those specify in the from clause. (This will
1066 * also prevent us from using the wrong table in inserts: eg.
1067 * tenk2 in "insert into tenk2 select * from tenk1;")
1071 legit_rtable = lappend(legit_rtable, rte);
1074 foreach(rt, legit_rtable)
1076 RangeTblEntry *rte = lfirst(rt);
1077 List *temp = target;
1080 target = expandAll(pstate, rte->relname, rte->refname,
1081 &pstate->p_last_resno);
1084 while (temp != NIL && lnext(temp) != NIL)
1086 lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
1087 &pstate->p_last_resno);
1096 * if the name of the resulting column is not specified in the target
1097 * list, we have to guess.
1101 figureColname(Node *expr, Node *resval)
1103 switch (nodeTag(expr))
1106 return (char *) /* XXX */
1107 ((Aggreg *) expr)->aggname;
1109 if (((Expr *) expr)->opType == FUNC_EXPR)
1111 if (nodeTag(resval) == T_FuncCall)
1112 return ((FuncCall *) resval)->funcname;
1122 /*****************************************************************************
1126 *****************************************************************************/
1130 * generate a list of column names if not supplied or
1131 * test supplied column names to make sure they are in target table
1132 * (used exclusively for inserts)
1135 makeTargetNames(ParseState *pstate, List *cols)
1139 /* Generate ResTarget if not supplied */
1145 AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
1147 numcol = pstate->p_target_relation->rd_rel->relnatts;
1148 for (i = 0; i < numcol; i++)
1150 Ident *id = makeNode(Ident);
1152 id->name = palloc(NAMEDATALEN);
1153 strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN - 1);
1154 id->indirection = NIL;
1157 cols = tl = lcons(id, NIL);
1160 lnext(tl) = lcons(id, NIL);
1170 char *name = ((Ident *) lfirst(tl))->name;
1172 /* elog on failure */
1173 varattno(pstate->p_target_relation, name);
1174 foreach(nxt, lnext(tl))
1175 if (!strcmp(name, ((Ident *) lfirst(nxt))->name))
1176 elog (WARN, "Attribute %s should be specified only once", name);
1184 * transformTargetList -
1185 * turns a list of ResTarget's into a list of TargetEntry's
1188 transformTargetList(ParseState *pstate, List *targetlist)
1190 List *p_target = NIL;
1191 List *tail_p_target = NIL;
1193 while (targetlist != NIL)
1195 ResTarget *res = (ResTarget *) lfirst(targetlist);
1196 TargetEntry *tent = makeNode(TargetEntry);
1198 switch (nodeTag(res->val))
1208 identname = ((Ident *) res->val)->name;
1209 handleTargetColname(pstate, &res->name, NULL, identname);
1212 * here we want to look for column names only, not
1217 * names (even though they can be stored in Ident
1221 expr = transformIdent(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1222 type_id = exprType(expr);
1223 type_len = tlen(get_id_type(type_id));
1224 resname = (res->name) ? res->name : identname;
1225 tent->resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
1241 Node *expr = transformExpr(pstate, (Node *) res->val, EXPR_COLUMN_FIRST);
1243 handleTargetColname(pstate, &res->name, NULL, NULL);
1244 /* note indirection has not been transformed */
1245 if (pstate->p_is_insert && res->indirection != NIL)
1247 /* this is an array assignment */
1260 if (exprType(expr) != UNKNOWNOID ||
1262 elog(WARN, "yyparse: string constant expected");
1264 val = (char *) textout((struct varlena *)
1265 ((Const *) expr)->constvalue);
1266 str = save_str = (char *) palloc(strlen(val) + MAXDIM * 25 + 2);
1267 foreach(elt, res->indirection)
1269 A_Indices *aind = (A_Indices *) lfirst(elt);
1271 aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
1272 if (!IsA(aind->uidx, Const))
1274 "Array Index for Append should be a constant");
1275 uindx[i] = ((Const *) aind->uidx)->constvalue;
1276 if (aind->lidx != NULL)
1278 aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
1279 if (!IsA(aind->lidx, Const))
1281 "Array Index for Append should be a constant");
1282 lindx[i] = ((Const *) aind->lidx)->constvalue;
1288 if (lindx[i] > uindx[i])
1289 elog(WARN, "yyparse: lower index cannot be greater than upper index");
1290 sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
1294 sprintf(str, "=%s", val);
1295 rd = pstate->p_target_relation;
1297 resdomno = varattno(rd, res->name);
1298 ndims = att_attnelems(rd, resdomno);
1300 elog(WARN, "yyparse: array dimensions do not match");
1301 constval = makeNode(Value);
1302 constval->type = T_String;
1303 constval->val.str = save_str;
1304 tent = make_targetlist_expr(pstate, res->name,
1305 (Node *) make_const(constval),
1311 char *colname = res->name;
1313 /* this is not an array assignment */
1314 if (colname == NULL)
1318 * if you're wondering why this is here, look
1319 * at the yacc grammar for why a name can be
1322 colname = figureColname(expr, res->val);
1324 if (res->indirection)
1326 List *ilist = res->indirection;
1328 while (ilist != NIL)
1330 A_Indices *ind = lfirst(ilist);
1332 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1333 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1334 ilist = lnext(ilist);
1337 res->name = colname;
1338 tent = make_targetlist_expr(pstate, res->name, expr,
1347 Attr *att = (Attr *) res->val;
1352 List *attrs = att->attrs;
1355 * Target item is a single '*', expand all tables (eg.
1356 * SELECT * FROM emp)
1358 if (att->relname != NULL && !strcmp(att->relname, "*"))
1360 if (tail_p_target == NIL)
1361 p_target = tail_p_target = expandAllTables(pstate);
1363 lnext(tail_p_target) = expandAllTables(pstate);
1365 while (lnext(tail_p_target) != NIL)
1366 /* make sure we point to the last target entry */
1367 tail_p_target = lnext(tail_p_target);
1370 * skip rest of while loop
1372 targetlist = lnext(targetlist);
1377 * Target item is relation.*, expand the table (eg.
1378 * SELECT emp.*, dname FROM emp, dept)
1380 attrname = strVal(lfirst(att->attrs));
1381 if (att->attrs != NIL && !strcmp(attrname, "*"))
1385 * tail_p_target is the target list we're building
1386 * in the while loop. Make sure we fix it after
1387 * appending more nodes.
1389 if (tail_p_target == NIL)
1390 p_target = tail_p_target = expandAll(pstate, att->relname,
1391 att->relname, &pstate->p_last_resno);
1393 lnext(tail_p_target) =
1394 expandAll(pstate, att->relname, att->relname,
1395 &pstate->p_last_resno);
1396 while (lnext(tail_p_target) != NIL)
1397 /* make sure we point to the last target entry */
1398 tail_p_target = lnext(tail_p_target);
1401 * skip the rest of the while loop
1403 targetlist = lnext(targetlist);
1409 * Target item is fully specified: ie.
1410 * relation.attribute
1412 result = handleNestedDots(pstate, att, &pstate->p_last_resno);
1413 handleTargetColname(pstate, &res->name, att->relname, attrname);
1414 if (att->indirection != NIL)
1416 List *ilist = att->indirection;
1418 while (ilist != NIL)
1420 A_Indices *ind = lfirst(ilist);
1422 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1423 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1424 ilist = lnext(ilist);
1426 result = (Node *) make_array_ref(result, att->indirection);
1428 type_id = exprType(result);
1429 type_len = tlen(get_id_type(type_id));
1430 /* move to last entry */
1431 while (lnext(attrs) != NIL)
1432 attrs = lnext(attrs);
1433 resname = (res->name) ? res->name : strVal(lfirst(attrs));
1434 resnode = makeResdom((AttrNumber) pstate->p_last_resno++,
1441 tent->resdom = resnode;
1442 tent->expr = result;
1446 /* internal error */
1448 "internal error: do not know how to transform targetlist");
1452 if (p_target == NIL)
1454 p_target = tail_p_target = lcons(tent, NIL);
1458 lnext(tail_p_target) = lcons(tent, NIL);
1459 tail_p_target = lnext(tail_p_target);
1461 targetlist = lnext(targetlist);
1469 * make_targetlist_expr -
1470 * make a TargetEntry from an expression
1472 * arrayRef is a list of transformed A_Indices
1474 static TargetEntry *
1475 make_targetlist_expr(ParseState *pstate,
1491 elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
1493 type_id = exprType(expr);
1494 if (type_id == InvalidOid)
1499 type_len = tlen(get_id_type(type_id));
1501 /* I have no idea what the following does! */
1502 /* It appears to process target columns that will be receiving results */
1503 if (pstate->p_is_insert || pstate->p_is_update)
1507 * append or replace query -- append, replace work only on one
1508 * relation, so multiple occurence of same resdomno is bogus
1510 rd = pstate->p_target_relation;
1512 resdomno = varattno(rd, colname);
1513 attrisset = varisset(rd, colname);
1514 attrtype = att_typeid(rd, resdomno);
1515 if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
1516 attrtype = GetArrayElementType(attrtype);
1517 if (attrtype == BPCHAROID || attrtype == VARCHAROID)
1519 attrlen = rd->rd_att->attrs[resdomno - 1]->attlen;
1523 attrlen = tlen(get_id_type(attrtype));
1526 if (Input_is_string && Typecast_ok)
1530 if (type_id == typeid(type("unknown")))
1532 val = (Datum) textout((struct varlena *)
1533 ((Const) lnext(expr))->constvalue);
1537 val = ((Const) lnext(expr))->constvalue;
1541 lnext(expr) = makeConst(attrtype,
1554 (Datum) fmgr(typeid_get_retinfunc(attrtype),
1555 val, get_typelem(attrtype), -1),
1557 true /* Maybe correct-- 80% chance */ ,
1558 false, /* is not a set */
1562 else if ((Typecast_ok) && (attrtype != type_id))
1565 parser_typecast2(expr, get_id_type(attrtype));
1567 else if (attrtype != type_id)
1569 if ((attrtype == INT2OID) && (type_id == INT4OID))
1570 lfirst(expr) = lispInteger(INT2OID); /* handle CASHOID too */
1571 else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
1572 lfirst(expr) = lispInteger(FLOAT4OID);
1574 elog(WARN, "unequal type in tlist : %s \n", colname);
1577 Input_is_string = false;
1578 Input_is_integer = false;
1582 if (attrtype != type_id)
1584 if (IsA(expr, Const))
1586 /* try to cast the constant */
1587 if (arrayRef && !(((A_Indices *) lfirst(arrayRef))->lidx))
1589 /* updating a single item */
1590 Oid typelem = get_typelem(attrtype);
1592 expr = (Node *) parser_typecast2(expr,
1594 get_id_type(typelem),
1598 expr = (Node *) parser_typecast2(expr,
1600 get_id_type(attrtype),
1605 /* currently, we can't handle casting of expressions */
1606 elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
1608 get_id_typname(attrtype),
1609 get_id_typname(type_id));
1613 if (arrayRef != NIL)
1616 Attr *att = makeNode(Attr);
1617 List *ar = arrayRef;
1618 List *upperIndexpr = NIL;
1619 List *lowerIndexpr = NIL;
1621 att->relname = pstrdup(RelationGetRelationName(rd)->data);
1622 att->attrs = lcons(makeString(colname), NIL);
1623 target_expr = (Expr *) handleNestedDots(pstate, att,
1624 &pstate->p_last_resno);
1627 A_Indices *ind = lfirst(ar);
1629 if (lowerIndexpr || (!upperIndexpr && ind->lidx))
1633 * XXX assume all lowerIndexpr is non-null in this
1636 lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
1638 upperIndexpr = lappend(upperIndexpr, ind->uidx);
1642 expr = (Node *) make_array_set(target_expr,
1646 attrtype = att_typeid(rd, resdomno);
1647 attrlen = tlen(get_id_type(attrtype));
1652 resdomno = pstate->p_last_resno++;
1656 tent = makeNode(TargetEntry);
1658 resnode = makeResdom((AttrNumber) resdomno,
1666 tent->resdom = resnode;
1673 /*****************************************************************************
1677 *****************************************************************************/
1680 * transformWhereClause -
1681 * transforms the qualification and make sure it is of type Boolean
1685 transformWhereClause(ParseState *pstate, Node *a_expr)
1690 return (Node *) NULL; /* no qualifiers */
1692 inWhereClause = true;
1693 qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
1694 inWhereClause = false;
1695 if (exprType(qual) != BOOLOID)
1698 "where clause must return type bool, not %s",
1699 tname(get_id_type(exprType(qual))));
1704 /*****************************************************************************
1708 *****************************************************************************/
1711 * find_targetlist_entry -
1712 * returns the Resdom in the target list matching the specified varname
1716 static TargetEntry *
1717 find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
1720 int real_rtable_pos = 0,
1722 TargetEntry *target_result = NULL;
1724 if (sortgroupby->range)
1725 real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
1726 sortgroupby->range);
1730 TargetEntry *target = (TargetEntry *) lfirst(i);
1731 Resdom *resnode = target->resdom;
1732 Var *var = (Var *) target->expr;
1733 char *resname = resnode->resname;
1734 int test_rtable_pos = var->varno;
1737 printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
1738 (sortgroupby->name ? sortgroupby->name : "(null)"), target_pos + 1, sortgroupby->resno);
1741 if (!sortgroupby->name)
1743 if (sortgroupby->resno == ++target_pos)
1745 target_result = target;
1751 if (!strcmp(resname, sortgroupby->name))
1753 if (sortgroupby->range)
1755 if (real_rtable_pos == test_rtable_pos)
1757 if (target_result != NULL)
1758 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1760 target_result = target;
1765 if (target_result != NULL)
1766 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1768 target_result = target;
1773 return target_result;
1777 any_ordering_op(int restype)
1782 order_op = oper("<", restype, restype, false);
1783 order_opid = oprid(order_op);
1789 * transformGroupClause -
1790 * transform a Group By clause
1794 transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
1799 while (grouplist != NIL)
1801 GroupClause *grpcl = makeNode(GroupClause);
1802 TargetEntry *restarget;
1805 restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
1807 if (restarget == NULL)
1808 elog(WARN, "The field being grouped by must appear in the target list");
1810 grpcl->entry = restarget;
1811 resdom = restarget->resdom;
1812 grpcl->grpOpoid = oprid(oper("<",
1814 resdom->restype, false));
1816 gl = glist = lcons(grpcl, NIL);
1823 GroupClause *gcl = (GroupClause *) lfirst (i);
1825 if ( gcl->entry == grpcl->entry )
1828 if ( i == NIL ) /* not in grouplist already */
1830 lnext(gl) = lcons(grpcl, NIL);
1834 pfree (grpcl); /* get rid of this */
1836 grouplist = lnext(grouplist);
1843 * transformSortClause -
1844 * transform an Order By clause
1848 transformSortClause(ParseState *pstate,
1849 List *orderlist, List *targetlist,
1852 List *sortlist = NIL;
1855 while (orderlist != NIL)
1857 SortGroupBy *sortby = lfirst(orderlist);
1858 SortClause *sortcl = makeNode(SortClause);
1859 TargetEntry *restarget;
1862 restarget = find_targetlist_entry(pstate, sortby, targetlist);
1863 if (restarget == NULL)
1864 elog(WARN, "The field being ordered by must appear in the target list");
1866 sortcl->resdom = resdom = restarget->resdom;
1867 sortcl->opoid = oprid(oper(sortby->useOp,
1869 resdom->restype, false));
1870 if (sortlist == NIL)
1872 s = sortlist = lcons(sortcl, NIL);
1878 foreach (i, sortlist)
1880 SortClause *scl = (SortClause *) lfirst (i);
1882 if ( scl->resdom == sortcl->resdom )
1885 if ( i == NIL ) /* not in sortlist already */
1887 lnext(s) = lcons(sortcl, NIL);
1891 pfree (sortcl); /* get rid of this */
1893 orderlist = lnext(orderlist);
1900 if (uniqueFlag[0] == '*')
1904 * concatenate all elements from target list that are not
1905 * already in the sortby list
1907 foreach(i, targetlist)
1909 TargetEntry *tlelt = (TargetEntry *) lfirst(i);
1914 SortClause *sortcl = lfirst(s);
1916 if (sortcl->resdom == tlelt->resdom)
1922 /* not a member of the sortclauses yet */
1923 SortClause *sortcl = makeNode(SortClause);
1925 sortcl->resdom = tlelt->resdom;
1926 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1928 sortlist = lappend(sortlist, sortcl);
1934 TargetEntry *tlelt = NULL;
1935 char *uniqueAttrName = uniqueFlag;
1937 /* only create sort clause with the specified unique attribute */
1938 foreach(i, targetlist)
1940 tlelt = (TargetEntry *) lfirst(i);
1941 if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
1946 elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
1949 foreach(s, sortlist)
1951 SortClause *sortcl = lfirst(s);
1953 if (sortcl->resdom == tlelt->resdom)
1958 /* not a member of the sortclauses yet */
1959 SortClause *sortcl = makeNode(SortClause);
1961 sortcl->resdom = tlelt->resdom;
1962 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1964 sortlist = lappend(sortlist, sortcl);
1974 ** HandleNestedDots --
1975 ** Given a nested dot expression (i.e. (relation func ... attr), build up
1976 ** a tree with of Iter and Func nodes.
1979 handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
1982 Node *retval = NULL;
1984 if (attr->paramNo != NULL)
1986 Param *param = (Param *) transformExpr(pstate, (Node *) attr->paramNo, EXPR_RELATION_FIRST);
1989 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1995 Ident *ident = makeNode(Ident);
1997 ident->name = attr->relname;
1998 ident->isRel = TRUE;
2000 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
2005 foreach(mutator_iter, lnext(attr->attrs))
2007 retval = ParseFunc(pstate, strVal(lfirst(mutator_iter)),
2016 ** make_arguments --
2017 ** Given the number and types of arguments to a function, and the
2018 ** actual arguments and argument types, do the necessary typecasting.
2021 make_arguments(int nargs,
2024 Oid *function_typeids)
2028 * there are two ways an input typeid can differ from a function
2029 * typeid : either the input type inherits the function type, so no
2030 * typecasting is necessary, or the input type can be typecast into
2031 * the function type. right now, we only typecast unknowns, and that
2032 * is all we check for.
2035 List *current_fargs;
2038 for (i = 0, current_fargs = fargs;
2040 i++, current_fargs = lnext(current_fargs))
2043 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid)
2045 lfirst(current_fargs) =
2046 parser_typecast2(lfirst(current_fargs),
2048 get_id_type(function_typeids[i]),
2056 ** Build a tlist that says which attribute to project to.
2057 ** This routine is called by ParseFunc() to set up a target list
2058 ** on a tuple parameter or return value. Due to a bug in 4.0,
2059 ** it's not possible to refer to system attributes in this case.
2062 setup_tlist(char *attname, Oid relid)
2070 attno = get_attnum(relid, attname);
2072 elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
2074 typeid = find_atttype(relid, attname);
2075 resnode = makeResdom(1,
2077 tlen(get_id_type(typeid)),
2078 get_attname(relid, attno),
2082 varnode = makeVar(-1, attno, typeid, -1, attno);
2084 tle = makeNode(TargetEntry);
2085 tle->resdom = resnode;
2086 tle->expr = (Node *) varnode;
2087 return (lcons(tle, NIL));
2091 ** setup_base_tlist --
2092 ** Build a tlist that extracts a base type from the tuple
2093 ** returned by the executor.
2096 setup_base_tlist(Oid typeid)
2102 resnode = makeResdom(1,
2104 tlen(get_id_type(typeid)),
2109 varnode = makeVar(-1, 1, typeid, -1, 1);
2110 tle = makeNode(TargetEntry);
2111 tle->resdom = resnode;
2112 tle->expr = (Node *) varnode;
2114 return (lcons(tle, NIL));
2118 * ParseComplexProjection -
2119 * handles function calls with a single argument that is of complex type.
2120 * This routine returns NULL if it can't handle the projection (eg. sets).
2123 ParseComplexProjection(ParseState *pstate,
2135 switch (nodeTag(first_arg))
2142 iter = (Iter *) first_arg;
2143 func = (Func *) ((Expr *) iter->iterexpr)->oper;
2144 argtype = funcid_get_rettype(func->funcid);
2145 argrelid = typeid_get_relid(argtype);
2147 ((attnum = get_attnum(argrelid, funcname))
2148 != InvalidAttrNumber))
2152 * the argument is a function returning a tuple, so
2153 * funcname may be a projection
2156 /* add a tlist to the func node and return the Iter */
2157 rd = heap_openr(tname(get_id_type(argtype)));
2158 if (RelationIsValid(rd))
2160 relid = RelationGetRelationId(rd);
2161 relname = RelationGetRelationName(rd);
2164 if (RelationIsValid(rd))
2167 setup_tlist(funcname, argrelid);
2168 iter->itertype = att_typeid(rd, attnum);
2169 return ((Node *) iter);
2174 "Function %s has bad returntype %d",
2189 * The argument is a set, so this is either a projection
2190 * or a function call on this set.
2197 Expr *expr = (Expr *) first_arg;
2200 if (expr->opType != FUNC_EXPR)
2203 funcnode = (Func *) expr->oper;
2204 argtype = funcid_get_rettype(funcnode->funcid);
2205 argrelid = typeid_get_relid(argtype);
2208 * the argument is a function returning a tuple, so
2209 * funcname may be a projection
2212 (attnum = get_attnum(argrelid, funcname))
2213 != InvalidAttrNumber)
2216 /* add a tlist to the func node */
2217 rd = heap_openr(tname(get_id_type(argtype)));
2218 if (RelationIsValid(rd))
2220 relid = RelationGetRelationId(rd);
2221 relname = RelationGetRelationName(rd);
2224 if (RelationIsValid(rd))
2228 funcnode->func_tlist =
2229 setup_tlist(funcname, argrelid);
2230 funcnode->functype = att_typeid(rd, attnum);
2232 newexpr = makeNode(Expr);
2233 newexpr->typeOid = funcnode->functype;
2234 newexpr->opType = FUNC_EXPR;
2235 newexpr->oper = (Node *) funcnode;
2236 newexpr->args = lcons(first_arg, NIL);
2238 return ((Node *) newexpr);
2243 elog(WARN, "Function %s has bad returntype %d",
2249 Param *param = (Param *) first_arg;
2252 * If the Param is a complex type, this could be a
2255 rd = heap_openr(tname(get_id_type(param->paramtype)));
2256 if (RelationIsValid(rd))
2258 relid = RelationGetRelationId(rd);
2259 relname = RelationGetRelationName(rd);
2262 if (RelationIsValid(rd) &&
2263 (attnum = get_attnum(relid, funcname))
2264 != InvalidAttrNumber)
2267 param->paramtype = att_typeid(rd, attnum);
2268 param->param_tlist = setup_tlist(funcname, relid);
2269 return ((Node *) param);
2281 ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
2283 Oid rettype = (Oid) 0;
2284 Oid argrelid = (Oid) 0;
2285 Oid funcid = (Oid) 0;
2287 Node *first_arg = NULL;
2288 char *relname = NULL;
2289 char *refname = NULL;
2295 Oid *true_oid_array;
2299 bool attisset = false;
2305 first_arg = lfirst(fargs);
2306 if (first_arg == NULL)
2307 elog(WARN, "function %s does not allow NULL input", funcname);
2311 * * check for projection methods: if function takes one argument, and *
2312 * that argument is a relation, param, or PQ function returning a
2313 * complex * type, then the function could be a projection.
2315 if (length(fargs) == 1)
2318 if (nodeTag(first_arg) == T_Ident && ((Ident *) first_arg)->isRel)
2321 Ident *ident = (Ident *) first_arg;
2324 * first arg is a relation. This could be a projection.
2326 refname = ident->name;
2328 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2330 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE, NULL);
2332 relname = rte->relname;
2336 * If the attr isn't a set, just make a var for it. If it is
2337 * a set, treat it like a function and drop through.
2339 if (get_attnum(relid, funcname) != InvalidAttrNumber)
2344 ((Node *) make_var(pstate,
2351 /* drop through - attr is a set */
2355 else if (ISCOMPLEX(exprType(first_arg)))
2359 * Attempt to handle projection of a complex argument. If
2360 * ParseComplexProjection can't handle the projection, we have
2363 retval = ParseComplexProjection(pstate,
2369 toid = exprType(first_arg);
2370 rd = heap_openr(tname(get_id_type(toid)));
2371 if (RelationIsValid(rd))
2373 relname = RelationGetRelationName(rd)->data;
2378 "Type %s is not a relation type",
2379 tname(get_id_type(toid)));
2380 argrelid = typeid_get_relid(toid);
2383 * A projection contains either an attribute name or the
2386 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
2387 && strcmp(funcname, "*"))
2389 elog(WARN, "Functions on sets are not yet supported");
2400 * Parsing aggregates.
2405 * the aggregate count is a special case, ignore its base
2406 * type. Treat it as zero
2408 if (strcmp(funcname, "count") == 0)
2411 basetype = exprType(lfirst(fargs));
2412 if (SearchSysCacheTuple(AGGNAME,
2413 PointerGetDatum(funcname),
2414 ObjectIdGetDatum(basetype),
2417 Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
2419 AddAggToParseState(pstate, aggreg);
2420 return (Node *) aggreg;
2427 * * If we dropped through to here it's really a function (or a set,
2428 * which * is implemented as a function.) * extract arg type info and
2429 * transform relation name arguments into * varnodes of the
2432 MemSet(&oid_array[0], 0, 8 * sizeof(Oid));
2439 Node *pair = lfirst(i);
2441 if (nodeTag(pair) == T_Ident && ((Ident *) pair)->isRel)
2447 refname = ((Ident *) pair)->name;
2449 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2451 rte = addRangeTableEntry(pstate, refname, refname,
2452 FALSE, FALSE, NULL);
2453 relname = rte->relname;
2455 vnum = refnameRangeTablePosn(pstate->p_rtable, rte->refname);
2458 * for func(relname), the param to the function is the tuple
2459 * under consideration. we build a special VarNode to reflect
2460 * this -- it has varno set to the correct range table entry,
2461 * but has varattno == 0 to signal that the whole tuple is the
2464 toid = typeid(type(relname));
2465 /* replace it in the arg list */
2467 makeVar(vnum, 0, toid, vnum, 0);
2470 { /* set functions don't have parameters */
2473 * any functiona args which are typed "unknown", but aren't
2474 * constants, we don't know what to do with, because we can't
2477 if (exprType(pair) == UNKNOWNOID &&
2480 elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
2483 toid = exprType(pair);
2486 oid_array[nargs++] = toid;
2490 * func_get_detail looks up the function in the catalogs, does
2491 * disambiguation for polymorphic functions, handles inheritance, and
2492 * returns the funcid and type and set or singleton status of the
2493 * function's return value. it also returns the true argument types
2494 * to the function. if func_get_detail returns true, the function
2495 * exists. otherwise, there was an error.
2498 { /* we know all of these fields already */
2501 * We create a funcnode with a placeholder function SetEval.
2502 * SetEval() never actually gets executed. When the function
2503 * evaluation routines see it, they use the funcid projected out
2504 * from the relation as the actual function to call. Example:
2505 * retrieve (emp.mgr.name) The plan for this will scan the emp
2506 * relation, projecting out the mgr attribute, which is a funcid.
2507 * This function is then called (instead of SetEval) and "name" is
2508 * projected from its result.
2510 funcid = SetEvalRegProcedure;
2513 true_oid_array = oid_array;
2518 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
2519 &rettype, &retset, &true_oid_array);
2523 elog(WARN, "no such attribute or function %s", funcname);
2526 funcnode = makeNode(Func);
2527 funcnode->funcid = funcid;
2528 funcnode->functype = rettype;
2529 funcnode->funcisindex = false;
2530 funcnode->funcsize = 0;
2531 funcnode->func_fcache = NULL;
2532 funcnode->func_tlist = NIL;
2533 funcnode->func_planlist = NIL;
2535 /* perform the necessary typecasting */
2536 make_arguments(nargs, fargs, oid_array, true_oid_array);
2539 * for functions returning base types, we want to project out the
2540 * return value. set up a target list to do that. the executor will
2541 * ignore these for c functions, and do the right thing for postquel
2545 if (typeid_get_relid(rettype) == InvalidOid)
2546 funcnode->func_tlist = setup_base_tlist(rettype);
2549 * For sets, we want to make a targetlist to project out this
2550 * attribute of the set tuples.
2554 if (!strcmp(funcname, "*"))
2556 funcnode->func_tlist =
2557 expandAll(pstate, relname, refname, curr_resno);
2561 funcnode->func_tlist = setup_tlist(funcname, argrelid);
2562 rettype = find_atttype(argrelid, funcname);
2567 * Sequence handling.
2569 if (funcid == SeqNextValueRegProcedure ||
2570 funcid == SeqCurrValueRegProcedure)
2575 int32 aclcheck_result = -1;
2576 extern text *lower (text *string);
2578 Assert(length(fargs) == 1);
2579 seq = (Const *) lfirst(fargs);
2580 if (!IsA((Node *) seq, Const))
2581 elog(WARN, "%s: only constant sequence names are acceptable", funcname);
2582 seqname = lower ((text*)DatumGetPointer(seq->constvalue));
2583 pfree (DatumGetPointer(seq->constvalue));
2584 seq->constvalue = PointerGetDatum (seqname);
2585 seqrel = textout(seqname);
2587 if ((aclcheck_result = pg_aclcheck(seqrel, GetPgUserName(),
2588 ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)))
2590 elog(WARN, "%s.%s: %s",
2591 seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
2595 if (funcid == SeqNextValueRegProcedure && inWhereClause)
2596 elog(WARN, "nextval of a sequence in WHERE disallowed");
2599 expr = makeNode(Expr);
2600 expr->typeOid = rettype;
2601 expr->opType = FUNC_EXPR;
2602 expr->oper = (Node *) funcnode;
2604 retval = (Node *) expr;
2607 * if the function returns a set of values, then we need to iterate
2608 * over all the returned values in the executor, so we stick an iter
2609 * node here. if it returns a singleton, then we don't need the iter
2615 Iter *iter = makeNode(Iter);
2617 iter->itertype = rettype;
2618 iter->iterexpr = retval;
2619 retval = (Node *) iter;
2625 /*****************************************************************************
2627 *****************************************************************************/
2630 * AddAggToParseState -
2631 * add the aggregate to the list of unique aggregates in pstate.
2633 * SIDE EFFECT: aggno in target list entry will be modified
2636 AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
2642 * see if we have the aggregate already (we only need to record the
2646 foreach(ag, pstate->p_aggs)
2648 Aggreg *a = lfirst(ag);
2650 if (!strcmp(a->aggname, aggreg->aggname) &&
2651 equal(a->target, aggreg->target))
2654 /* fill in the aggno and we're done */
2661 /* not found, new aggregate */
2664 pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
2669 * finalizeAggregates -
2670 * fill in qry_aggs from pstate. Also checks to make sure that aggregates
2671 * are used in the proper place.
2674 finalizeAggregates(ParseState *pstate, Query *qry)
2679 parseCheckAggregates(pstate, qry);
2681 qry->qry_numAgg = pstate->p_numAgg;
2683 (Aggreg **) palloc(sizeof(Aggreg *) * qry->qry_numAgg);
2685 foreach(l, pstate->p_aggs)
2686 qry->qry_aggs[i++] = (Aggreg *) lfirst(l);
2690 * contain_agg_clause--
2691 * Recursively find aggreg nodes from a clause.
2693 * Returns true if any aggregate found.
2696 contain_agg_clause(Node *clause)
2700 else if (IsA(clause, Aggreg))
2702 else if (IsA(clause, Iter))
2703 return contain_agg_clause(((Iter *) clause)->iterexpr);
2704 else if (single_node(clause))
2706 else if (or_clause(clause))
2710 foreach(temp, ((Expr *) clause)->args)
2711 if (contain_agg_clause(lfirst(temp)))
2715 else if (is_funcclause(clause))
2719 foreach(temp, ((Expr *) clause)->args)
2720 if (contain_agg_clause(lfirst(temp)))
2724 else if (IsA(clause, ArrayRef))
2728 foreach(temp, ((ArrayRef *) clause)->refupperindexpr)
2729 if (contain_agg_clause(lfirst(temp)))
2731 foreach(temp, ((ArrayRef *) clause)->reflowerindexpr)
2732 if (contain_agg_clause(lfirst(temp)))
2734 if (contain_agg_clause(((ArrayRef *) clause)->refexpr))
2736 if (contain_agg_clause(((ArrayRef *) clause)->refassgnexpr))
2740 else if (not_clause(clause))
2741 return contain_agg_clause((Node *) get_notclausearg((Expr *) clause));
2742 else if (is_opclause(clause))
2743 return (contain_agg_clause((Node *) get_leftop((Expr *) clause)) ||
2744 contain_agg_clause((Node *) get_rightop((Expr *) clause)));
2750 * exprIsAggOrGroupCol -
2751 * returns true if the expression does not contain non-group columns.
2754 exprIsAggOrGroupCol(Node *expr, List *groupClause)
2758 if (expr == NULL || IsA(expr, Const) ||
2759 IsA(expr, Param) ||IsA(expr, Aggreg))
2762 foreach(gl, groupClause)
2764 GroupClause *grpcl = lfirst(gl);
2766 if (equal(expr, grpcl->entry->expr))
2770 if (IsA(expr, Expr))
2774 foreach(temp, ((Expr *) expr)->args)
2775 if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2784 * tleIsAggOrGroupCol -
2785 * returns true if the TargetEntry is Agg or GroupCol.
2788 tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
2790 Node *expr = tle->expr;
2793 if (expr == NULL || IsA(expr, Const) ||IsA(expr, Param))
2796 foreach(gl, groupClause)
2798 GroupClause *grpcl = lfirst(gl);
2800 if (tle->resdom->resno == grpcl->entry->resdom->resno)
2802 if (contain_agg_clause((Node *) expr))
2803 elog(WARN, "parser: aggregates not allowed in GROUP BY clause");
2808 if (IsA(expr, Aggreg))
2811 if (IsA(expr, Expr))
2815 foreach(temp, ((Expr *) expr)->args)
2816 if (!exprIsAggOrGroupCol(lfirst(temp), groupClause))
2825 * parseCheckAggregates -
2826 * this should really be done earlier but the current grammar
2827 * cannot differentiate functions from aggregates. So we have do check
2828 * here when the target list and the qualifications are finalized.
2831 parseCheckAggregates(ParseState *pstate, Query *qry)
2835 Assert(pstate->p_numAgg > 0);
2838 * aggregates never appear in WHERE clauses. (we have to check where
2839 * clause first because if there is an aggregate, the check for
2840 * non-group column in target list may fail.)
2842 if (contain_agg_clause(qry->qual))
2843 elog(WARN, "parser: aggregates not allowed in WHERE clause");
2846 * the target list can only contain aggregates, group columns and
2847 * functions thereof.
2849 foreach(tl, qry->targetList)
2851 TargetEntry *tle = lfirst(tl);
2853 if (!tleIsAggOrGroupCol(tle, qry->groupClause))
2855 "parser: illegal use of aggregates or non-group column in target list");
2859 * the expression specified in the HAVING clause has the same
2860 * restriction as those in the target list.
2863 * Need to change here when we get HAVING works. Currently
2864 * qry->havingQual is NULL. - vadim 04/05/97
2865 if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
2867 "parser: illegal use of aggregates or non-group column in HAVING clause");