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.38 1997/09/05 19:32:31 momjian Exp $
12 *-------------------------------------------------------------------------
18 #include "nodes/nodes.h"
19 #include "nodes/params.h"
20 #include "nodes/primnodes.h"
21 #include "nodes/parsenodes.h"
22 #include "nodes/relation.h"
23 #include "parse.h" /* for AND, OR, etc. */
24 #include "catalog/pg_type.h" /* for INT4OID, etc. */
25 #include "catalog/pg_proc.h"
26 #include "utils/elog.h"
27 #include "utils/builtins.h" /* namecmp(), textout() */
28 #include "utils/lsyscache.h"
29 #include "utils/palloc.h"
30 #include "utils/mcxt.h"
31 #include "utils/syscache.h"
32 #include "utils/acl.h"
33 #include "parser/parse_query.h"
34 #include "parser/parse_state.h"
35 #include "nodes/makefuncs.h" /* for makeResdom(), etc. */
36 #include "nodes/nodeFuncs.h"
37 #include "commands/sequence.h"
39 #include "optimizer/clauses.h"
40 #include "access/heapam.h"
42 #include "miscadmin.h"
44 #include "port-protos.h" /* strdup() */
46 /* convert the parse tree into a query tree */
47 static Query *transformStmt(ParseState *pstate, Node *stmt);
49 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
50 static Query *transformInsertStmt(ParseState *pstate, AppendStmt *stmt);
51 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
52 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
53 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
54 static Query *transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt);
55 static Query *transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt);
56 static Query *transformCursorStmt(ParseState *pstate, CursorStmt *stmt);
57 static Node *handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno);
59 #define EXPR_COLUMN_FIRST 1
60 #define EXPR_RELATION_FIRST 2
61 static Node *transformExpr(ParseState *pstate, Node *expr, int precedence);
62 static Node *transformIdent(ParseState *pstate, Node *expr, int precedence);
64 static void makeRangeTable(ParseState *pstate, char *relname, List *frmList);
65 static List *expandAllTables(ParseState *pstate);
66 static char *figureColname(Node *expr, Node *resval);
67 static List *makeTargetNames(ParseState *pstate, List *cols);
68 static List *transformTargetList(ParseState *pstate, List *targetlist);
69 static TargetEntry *make_targetlist_expr(ParseState *pstate,
70 char *colname, Node *expr,
72 static bool inWhereClause = false;
73 static Node *transformWhereClause(ParseState *pstate, Node *a_expr);
74 static List *transformGroupClause(ParseState *pstate, List *grouplist,
76 static List *transformSortClause(ParseState *pstate,
77 List *orderlist, List *targetlist,
80 static void parseFromClause(ParseState *pstate, List *frmList);
81 static Node *ParseFunc(ParseState *pstate, char *funcname,
82 List *fargs, int *curr_resno);
83 static List *setup_tlist(char *attname, Oid relid);
84 static List *setup_base_tlist(Oid typeid);
85 static void make_arguments(int nargs, List *fargs, Oid *input_typeids,
86 Oid *function_typeids);
87 static void AddAggToParseState(ParseState *pstate, Aggreg *aggreg);
88 static void finalizeAggregates(ParseState *pstate, Query *qry);
89 static void parseCheckAggregates(ParseState *pstate, Query *qry);
90 static ParseState* makeParseState(void);
92 /*****************************************************************************
94 *****************************************************************************/
98 * allocate and initialize a new ParseState.
99 * the CALLERS is responsible for freeing the ParseState* returned
108 pstate = malloc(sizeof(ParseState));
109 pstate->p_last_resno = 1;
110 pstate->p_rtable = NIL;
111 pstate->p_numAgg = 0;
112 pstate->p_aggs = NIL;
113 pstate->p_is_insert = false;
114 pstate->p_insert_columns = NIL;
115 pstate->p_is_update = false;
116 pstate->p_is_rule = false;
117 pstate->p_target_relation = NULL;
118 pstate->p_target_rangetblentry = NULL;
125 * analyze a list of parse trees and transform them if necessary.
127 * Returns a list of transformed parse trees. Optimizable statements are
128 * all transformed to Query while the rest stays the same.
130 * CALLER is responsible for freeing the QueryTreeList* returned
133 parse_analyze(List *pl)
135 QueryTreeList *result;
139 result = malloc(sizeof(QueryTreeList));
140 result->len = length(pl);
141 result->qtrees = (Query**)malloc(result->len * sizeof(Query*));
143 inWhereClause = false; /* to avoid nextval(sequence) in WHERE */
146 pstate = makeParseState();
147 result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
149 if (pstate->p_target_relation != NULL)
150 heap_close(pstate->p_target_relation);
159 * transform a Parse tree. If it is an optimizable statement, turn it
163 transformStmt(ParseState* pstate, Node *parseTree)
165 Query* result = NULL;
167 switch(nodeTag(parseTree)) {
168 /*------------------------
169 * Non-optimizable statements
170 *------------------------
173 result = transformIndexStmt(pstate, (IndexStmt *)parseTree);
177 result = transformExtendStmt(pstate, (ExtendStmt *)parseTree);
181 result = transformRuleStmt(pstate, (RuleStmt *)parseTree);
186 ViewStmt *n = (ViewStmt *)parseTree;
187 n->query = (Query *)transformStmt(pstate, (Node*)n->query);
188 result = makeNode(Query);
189 result->commandType = CMD_UTILITY;
190 result->utilityStmt = (Node*)n;
196 MemoryContext oldcontext;
197 /* make sure that this Query is allocated in TopMemory context
198 because vacuum spans transactions and we don't want to lose
199 the vacuum Query due to end-of-transaction free'ing*/
200 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
201 result = makeNode(Query);
202 result->commandType = CMD_UTILITY;
203 result->utilityStmt = (Node*)parseTree;
204 MemoryContextSwitchTo(oldcontext);
210 ExplainStmt *n = (ExplainStmt *)parseTree;
211 result = makeNode(Query);
212 result->commandType = CMD_UTILITY;
213 n->query = transformStmt(pstate, (Node*)n->query);
214 result->utilityStmt = (Node*)parseTree;
218 /*------------------------
219 * Optimizable statements
220 *------------------------
223 result = transformInsertStmt(pstate, (AppendStmt *)parseTree);
227 result = transformDeleteStmt(pstate, (DeleteStmt *)parseTree);
231 result = transformUpdateStmt(pstate, (ReplaceStmt *)parseTree);
235 result = transformCursorStmt(pstate, (CursorStmt *)parseTree);
239 result = transformSelectStmt(pstate, (RetrieveStmt *)parseTree);
244 * other statments don't require any transformation-- just
245 * return the original parsetree
247 result = makeNode(Query);
248 result->commandType = CMD_UTILITY;
249 result->utilityStmt = (Node*)parseTree;
256 * transformDeleteStmt -
257 * transforms a Delete Statement
260 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
262 Query *qry = makeNode(Query);
264 qry->commandType = CMD_DELETE;
266 /* set up a range table */
267 makeRangeTable(pstate, stmt->relname, NULL);
269 qry->uniqueFlag = NULL;
271 /* fix where clause */
272 qry->qual = transformWhereClause(pstate, stmt->whereClause);
274 qry->rtable = pstate->p_rtable;
275 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
277 /* make sure we don't have aggregates in the where clause */
278 if (pstate->p_numAgg > 0)
279 parseCheckAggregates(pstate, qry);
285 * transformInsertStmt -
286 * transform an Insert Statement
289 transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
291 Query *qry = makeNode(Query); /* make a new query tree */
293 qry->commandType = CMD_INSERT;
294 pstate->p_is_insert = true;
296 /* set up a range table */
297 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
299 qry->uniqueFlag = NULL;
301 /* fix the target list */
302 pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
304 qry->targetList = transformTargetList(pstate, stmt->targetList);
306 /* fix where clause */
307 qry->qual = transformWhereClause(pstate, stmt->whereClause);
309 /* now the range table will not change */
310 qry->rtable = pstate->p_rtable;
311 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
313 if (pstate->p_numAgg > 0)
314 finalizeAggregates(pstate, qry);
320 * transformIndexStmt -
321 * transforms the qualification of the index statement
324 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
329 q->commandType = CMD_UTILITY;
331 /* take care of the where clause */
332 stmt->whereClause = transformWhereClause(pstate,stmt->whereClause);
333 stmt->rangetable = pstate->p_rtable;
335 q->utilityStmt = (Node*)stmt;
341 * transformExtendStmt -
342 * transform the qualifications of the Extend Index Statement
346 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
351 q->commandType = CMD_UTILITY;
353 /* take care of the where clause */
354 stmt->whereClause = transformWhereClause(pstate,stmt->whereClause);
355 stmt->rangetable = pstate->p_rtable;
357 q->utilityStmt = (Node*)stmt;
362 * transformRuleStmt -
363 * transform a Create Rule Statement. The actions is a list of parse
364 * trees which is transformed into a list of query trees.
367 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
373 q->commandType = CMD_UTILITY;
375 actions = stmt->actions;
377 * transform each statment, like parse_analyze()
379 while (actions != NIL) {
381 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
384 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
386 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
389 pstate->p_last_resno = 1;
390 pstate->p_is_rule = true; /* for expand all */
391 pstate->p_numAgg = 0;
392 pstate->p_aggs = NULL;
394 lfirst(actions) = transformStmt(pstate, lfirst(actions));
395 actions = lnext(actions);
398 /* take care of the where clause */
399 stmt->whereClause = transformWhereClause(pstate,stmt->whereClause);
401 q->utilityStmt = (Node*)stmt;
407 * transformSelectStmt -
408 * transforms a Select Statement
412 transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt)
414 Query *qry = makeNode(Query);
416 qry->commandType = CMD_SELECT;
418 /* set up a range table */
419 makeRangeTable(pstate, NULL, stmt->fromClause);
421 qry->uniqueFlag = stmt->unique;
423 qry->into = stmt->into;
424 qry->isPortal = FALSE;
426 /* fix the target list */
427 qry->targetList = transformTargetList(pstate, stmt->targetList);
429 /* fix where clause */
430 qry->qual = transformWhereClause(pstate,stmt->whereClause);
432 /* check subselect clause */
433 if (stmt->selectClause)
434 elog(NOTICE,"UNION not yet supported; using first SELECT only",NULL);
436 /* check subselect clause */
437 if (stmt->havingClause)
438 elog(NOTICE,"HAVING not yet supported; ignore clause",NULL);
440 /* fix order clause */
441 qry->sortClause = transformSortClause(pstate,
446 /* fix group by clause */
447 qry->groupClause = transformGroupClause(pstate,
450 qry->rtable = pstate->p_rtable;
452 if (pstate->p_numAgg > 0)
453 finalizeAggregates(pstate, qry);
459 * transformUpdateStmt -
460 * transforms an update statement
464 transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt)
466 Query *qry = makeNode(Query);
468 qry->commandType = CMD_UPDATE;
469 pstate->p_is_update = true;
471 * the FROM clause is non-standard SQL syntax. We used to be able to
472 * do this with REPLACE in POSTQUEL so we keep the feature.
474 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
476 /* fix the target list */
477 qry->targetList = transformTargetList(pstate, stmt->targetList);
479 /* fix where clause */
480 qry->qual = transformWhereClause(pstate,stmt->whereClause);
482 qry->rtable = pstate->p_rtable;
483 qry->resultRelation = refnameRangeTablePosn(pstate->p_rtable, stmt->relname);
485 /* make sure we don't have aggregates in the where clause */
486 if (pstate->p_numAgg > 0)
487 parseCheckAggregates(pstate, qry);
493 * transformCursorStmt -
494 * transform a Create Cursor Statement
498 transformCursorStmt(ParseState *pstate, CursorStmt *stmt)
500 Query *qry = makeNode(Query);
503 * in the old days, a cursor statement is a 'retrieve into portal';
504 * If you change the following, make sure you also go through the code
505 * in various places that tests the kind of operation.
507 qry->commandType = CMD_SELECT;
509 /* set up a range table */
510 makeRangeTable(pstate, NULL, stmt->fromClause);
512 qry->uniqueFlag = stmt->unique;
514 qry->into = stmt->portalname;
515 qry->isPortal = TRUE;
516 qry->isBinary = stmt->binary; /* internal portal */
518 /* fix the target list */
519 qry->targetList = transformTargetList(pstate, stmt->targetList);
521 /* fix where clause */
522 qry->qual = transformWhereClause(pstate,stmt->whereClause);
524 /* fix order clause */
525 qry->sortClause = transformSortClause(pstate,
529 /* fix group by clause */
530 qry->groupClause = transformGroupClause(pstate,
534 qry->rtable = pstate->p_rtable;
536 if (pstate->p_numAgg > 0)
537 finalizeAggregates(pstate, qry);
542 /*****************************************************************************
544 * Transform Exprs, Aggs, etc.
546 *****************************************************************************/
550 * analyze and transform expressions. Type checking and type casting is
551 * done here. The optimizer and the executor cannot handle the original
552 * (raw) expressions collected by the parse tree. Hence the transformation
556 transformExpr(ParseState *pstate, Node *expr, int precedence)
563 switch(nodeTag(expr)) {
565 Attr *att = (Attr *)expr;
568 /* what if att.attrs == "*"?? */
569 temp = handleNestedDots(pstate, att, &pstate->p_last_resno);
570 if (att->indirection != NIL) {
571 List *idx = att->indirection;
573 A_Indices *ai = (A_Indices *)lfirst(idx);
574 Node *lexpr=NULL, *uexpr;
575 uexpr = transformExpr(pstate, ai->uidx, precedence); /* must exists */
576 if (exprType(uexpr) != INT4OID)
577 elog(WARN, "array index expressions must be int4's");
578 if (ai->lidx != NULL) {
579 lexpr = transformExpr(pstate, ai->lidx, precedence);
580 if (exprType(lexpr) != INT4OID)
581 elog(WARN, "array index expressions must be int4's");
585 if (ai->lidx!=NULL) pfree(ai->lidx);
589 /* note we reuse the list of indices, make sure we don't free
590 them! Otherwise, make a new list here */
593 result = (Node*)make_array_ref(temp, att->indirection);
600 A_Const *con= (A_Const *)expr;
601 Value *val = &con->val;
602 if (con->typename != NULL) {
603 result = parser_typecast(val, con->typename, -1);
605 result = (Node *)make_const(val);
610 ParamNo *pno = (ParamNo *)expr;
615 paramno = pno->number;
616 toid = param_type(paramno);
617 if (!OidIsValid(toid)) {
618 elog(WARN, "Parameter '$%d' is out of range",
621 param = makeNode(Param);
622 param->paramkind = PARAM_NUM;
623 param->paramid = (AttrNumber) paramno;
624 param->paramname = "<unnamed>";
625 param->paramtype = (Oid)toid;
626 param->param_tlist = (List*) NULL;
628 result = (Node *)param;
632 A_Expr *a = (A_Expr *)expr;
637 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
638 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
639 result = (Node *)make_op(a->opname, lexpr, rexpr);
644 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
645 result = ParseFunc(pstate,
646 "nullvalue", lcons(lexpr, NIL),
647 &pstate->p_last_resno);
652 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
653 result = ParseFunc(pstate,
654 "nonnullvalue", lcons(lexpr, NIL),
655 &pstate->p_last_resno);
660 Expr *expr = makeNode(Expr);
661 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
662 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
663 if (exprType(lexpr) != BOOLOID)
665 "left-hand side of AND is type '%s', not bool",
666 tname(get_id_type(exprType(lexpr))));
667 if (exprType(rexpr) != BOOLOID)
669 "right-hand side of AND is type '%s', not bool",
670 tname(get_id_type(exprType(rexpr))));
671 expr->typeOid = BOOLOID;
672 expr->opType = AND_EXPR;
673 expr->args = makeList(lexpr, rexpr, -1);
674 result = (Node *)expr;
679 Expr *expr = makeNode(Expr);
680 Node *lexpr = transformExpr(pstate, a->lexpr, precedence);
681 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
682 if (exprType(lexpr) != BOOLOID)
684 "left-hand side of OR is type '%s', not bool",
685 tname(get_id_type(exprType(lexpr))));
686 if (exprType(rexpr) != BOOLOID)
688 "right-hand side of OR is type '%s', not bool",
689 tname(get_id_type(exprType(rexpr))));
690 expr->typeOid = BOOLOID;
691 expr->opType = OR_EXPR;
692 expr->args = makeList(lexpr, rexpr, -1);
693 result = (Node *)expr;
698 Expr *expr = makeNode(Expr);
699 Node *rexpr = transformExpr(pstate, a->rexpr, precedence);
700 if (exprType(rexpr) != BOOLOID)
702 "argument to NOT is type '%s', not bool",
703 tname(get_id_type(exprType(rexpr))));
704 expr->typeOid = BOOLOID;
705 expr->opType = NOT_EXPR;
706 expr->args = makeList(rexpr, -1);
707 result = (Node *)expr;
714 /* look for a column name or a relation name (the default behavior) */
715 result = transformIdent(pstate, expr, precedence);
719 FuncCall *fn = (FuncCall *)expr;
722 /* transform the list of arguments */
723 foreach(args, fn->args)
724 lfirst(args) = transformExpr(pstate, (Node*)lfirst(args), precedence);
725 result = ParseFunc(pstate,
726 fn->funcname, fn->args, &pstate->p_last_resno);
730 /* should not reach here */
731 elog(WARN, "transformExpr: does not know how to transform %d\n",
740 transformIdent(ParseState *pstate, Node *expr, int precedence)
742 Ident *ident = (Ident*)expr;
744 Node *column_result, *relation_result, *result;
746 column_result = relation_result = result = 0;
747 /* try to find the ident as a column */
748 if ((rte = colnameRangeTableEntry(pstate, ident->name)) != NULL) {
749 Attr *att = makeNode(Attr);
751 att->relname = rte->refname;
752 att->attrs = lcons(makeString(ident->name), NIL);
754 (Node*)handleNestedDots(pstate, att, &pstate->p_last_resno);
757 /* try to find the ident as a relation */
758 if (refnameRangeTableEntry(pstate->p_rtable, ident->name) != NULL) {
760 relation_result = (Node*)ident;
763 /* choose the right result based on the precedence */
764 if(precedence == EXPR_COLUMN_FIRST) {
766 result = column_result;
768 result = relation_result;
771 result = relation_result;
773 result = column_result;
777 elog(WARN, "attribute \"%s\" not found", ident->name);
782 /*****************************************************************************
786 *****************************************************************************/
790 * turns the table references specified in the from-clause into a
791 * range table. The range table may grow as we transform the expressions
792 * in the target list. (Note that this happens because in POSTQUEL, we
793 * allow references to relations not specified in the from-clause. We
794 * also allow that in our POST-SQL)
798 parseFromClause(ParseState *pstate, List *frmList)
804 RangeVar *r = lfirst(fl);
805 RelExpr *baserel = r->relExpr;
806 char *relname = baserel->relname;
807 char *refname = r->name;
814 * marks this entry to indicate it comes from the FROM clause. In
815 * SQL, the target list can only refer to range variables specified
816 * in the from clause but we follow the more powerful POSTQUEL
817 * semantics and automatically generate the range variable if not
818 * specified. However there are times we need to know whether the
819 * entries are legitimate.
821 * eg. select * from foo f where f.x = 1; will generate wrong answer
822 * if we expand * to foo.x.
824 rte = addRangeTableEntry(pstate, relname, refname, baserel->inh, TRUE,
831 * make a range table with the specified relation (optional) and the
835 makeRangeTable(ParseState *pstate, char *relname, List *frmList)
839 parseFromClause(pstate, frmList);
844 if (refnameRangeTablePosn(pstate->p_rtable, relname) < 1)
845 rte = addRangeTableEntry(pstate, relname, relname, FALSE, FALSE, NULL);
847 rte = refnameRangeTableEntry(pstate->p_rtable, relname);
849 pstate->p_target_rangetblentry = rte;
850 Assert(pstate->p_target_relation == NULL);
851 pstate->p_target_relation = heap_open(rte->relid);
852 Assert(pstate->p_target_relation != NULL);
853 /* will close relation later */
858 * returns the Oid of the type of the expression. (Used for typechecking.)
865 switch(nodeTag(expr)) {
867 type = ((Func*)expr)->functype;
870 type = ((Iter*)expr)->itertype;
873 type = ((Var*)expr)->vartype;
876 type = ((Expr*)expr)->typeOid;
879 type = ((Const*)expr)->consttype;
882 type = ((ArrayRef*)expr)->refelemtype;
885 type = ((Aggreg*)expr)->aggtype;
888 type = ((Param*)expr)->paramtype;
895 elog(WARN, "exprType: don't know how to get type for %d node",
904 * turns '*' (in the target list) into a list of attributes (of all
905 * relations in the range table)
908 expandAllTables(ParseState *pstate)
911 List *legit_rtable=NIL;
914 rtable = pstate->p_rtable;
915 if (pstate->p_is_rule) {
917 * skip first two entries, "*new*" and "*current*"
919 rtable = lnext(lnext(pstate->p_rtable));
922 /* this should not happen */
924 elog(WARN, "cannot expand: null p_rtable");
927 * go through the range table and make a list of range table entries
928 * which we will expand.
930 foreach(rt, rtable) {
931 RangeTblEntry *rte = lfirst(rt);
934 * we only expand those specify in the from clause. (This will
935 * also prevent us from using the wrong table in inserts: eg. tenk2
936 * in "insert into tenk2 select * from tenk1;")
940 legit_rtable = lappend(legit_rtable, rte);
943 foreach(rt, legit_rtable) {
944 RangeTblEntry *rte = lfirst(rt);
948 target = expandAll(pstate, rte->relname, rte->refname,
949 &pstate->p_last_resno);
951 while (temp != NIL && lnext(temp) != NIL)
953 lnext(temp) = expandAll(pstate, rte->relname, rte->refname,
954 &pstate->p_last_resno);
963 * if the name of the resulting column is not specified in the target
964 * list, we have to guess.
968 figureColname(Node *expr, Node *resval)
970 switch (nodeTag(expr)) {
972 return (char*) /* XXX */
973 ((Aggreg *)expr)->aggname;
975 if (((Expr*)expr)->opType == FUNC_EXPR) {
976 if (nodeTag(resval)==T_FuncCall)
977 return ((FuncCall*)resval)->funcname;
987 /*****************************************************************************
991 *****************************************************************************/
995 * generate a list of column names if not supplied or
996 * test supplied column names to make sure they are in target table
997 * (used exclusively for inserts)
1000 makeTargetNames(ParseState *pstate, List *cols)
1004 /* Generate ResTarget if not supplied */
1009 AttributeTupleForm *attr = pstate->p_target_relation->rd_att->attrs;
1011 numcol = pstate->p_target_relation->rd_rel->relnatts;
1012 for(i=0; i < numcol; i++) {
1013 Ident *id = makeNode(Ident);
1015 id->name = palloc(NAMEDATALEN);
1016 strNcpy(id->name, attr[i]->attname.data, NAMEDATALEN-1);
1017 id->indirection = NIL;
1020 cols = tl = lcons(id, NIL);
1022 lnext(tl) = lcons(id,NIL);
1029 /* elog on failure */
1030 varattno(pstate->p_target_relation,((Ident *)lfirst(tl))->name);
1036 * transformTargetList -
1037 * turns a list of ResTarget's into a list of TargetEntry's
1040 transformTargetList(ParseState *pstate, List *targetlist)
1042 List *p_target= NIL;
1043 List *tail_p_target = NIL;
1045 while(targetlist != NIL) {
1046 ResTarget *res= (ResTarget *)lfirst(targetlist);
1047 TargetEntry *tent = makeNode(TargetEntry);
1049 switch(nodeTag(res->val)) {
1057 identname = ((Ident*)res->val)->name;
1058 handleTargetColname(pstate, &res->name, NULL, identname );
1060 /* here we want to look for column names only, not relation */
1061 /* names (even though they can be stored in Ident nodes, */
1063 expr = transformIdent(pstate, (Node*)res->val, EXPR_COLUMN_FIRST);
1064 type_id = exprType(expr);
1065 type_len = tlen(get_id_type(type_id));
1066 resname = (res->name) ? res->name : identname;
1067 tent->resdom = makeResdom((AttrNumber)pstate->p_last_resno++,
1082 Node *expr = transformExpr(pstate, (Node *)res->val, EXPR_COLUMN_FIRST);
1084 handleTargetColname(pstate, &res->name, NULL, NULL);
1085 /* note indirection has not been transformed */
1086 if (pstate->p_is_insert && res->indirection!=NIL) {
1087 /* this is an array assignment */
1089 char *str, *save_str;
1092 int lindx[MAXDIM], uindx[MAXDIM];
1097 if (exprType(expr) != UNKNOWNOID ||
1099 elog(WARN, "yyparse: string constant expected");
1101 val = (char *) textout((struct varlena *)
1102 ((Const *)expr)->constvalue);
1103 str = save_str = (char*)palloc(strlen(val) + MAXDIM * 25 + 2);
1104 foreach(elt, res->indirection) {
1105 A_Indices *aind = (A_Indices *)lfirst(elt);
1106 aind->uidx = transformExpr(pstate, aind->uidx, EXPR_COLUMN_FIRST);
1107 if (!IsA(aind->uidx,Const))
1109 "Array Index for Append should be a constant");
1110 uindx[i] = ((Const *)aind->uidx)->constvalue;
1111 if (aind->lidx!=NULL) {
1112 aind->lidx = transformExpr(pstate, aind->lidx, EXPR_COLUMN_FIRST);
1113 if (!IsA(aind->lidx,Const))
1115 "Array Index for Append should be a constant");
1116 lindx[i] = ((Const*)aind->lidx)->constvalue;
1120 if (lindx[i] > uindx[i])
1121 elog(WARN, "yyparse: lower index cannot be greater than upper index");
1122 sprintf(str, "[%d:%d]", lindx[i], uindx[i]);
1126 sprintf(str, "=%s", val);
1127 rd = pstate->p_target_relation;
1129 resdomno = varattno(rd, res->name);
1130 ndims = att_attnelems(rd, resdomno);
1132 elog(WARN, "yyparse: array dimensions do not match");
1133 constval = makeNode(Value);
1134 constval->type = T_String;
1135 constval->val.str = save_str;
1136 tent = make_targetlist_expr(pstate, res->name,
1137 (Node*)make_const(constval),
1141 char *colname= res->name;
1142 /* this is not an array assignment */
1143 if (colname==NULL) {
1144 /* if you're wondering why this is here, look at
1145 * the yacc grammar for why a name can be missing. -ay
1147 colname = figureColname(expr, res->val);
1149 if (res->indirection) {
1150 List *ilist = res->indirection;
1151 while (ilist!=NIL) {
1152 A_Indices *ind = lfirst(ilist);
1153 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1154 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1155 ilist = lnext(ilist);
1158 res->name = colname;
1159 tent = make_targetlist_expr(pstate, res->name, expr,
1167 Attr *att = (Attr *)res->val;
1172 List *attrs = att->attrs;
1175 * Target item is a single '*', expand all tables
1176 * (eg. SELECT * FROM emp)
1178 if (att->relname!=NULL && !strcmp(att->relname, "*")) {
1179 if (tail_p_target == NIL)
1180 p_target = tail_p_target = expandAllTables(pstate);
1182 lnext(tail_p_target) = expandAllTables(pstate);
1184 while(lnext(tail_p_target)!=NIL)
1185 /* make sure we point to the last target entry */
1186 tail_p_target = lnext(tail_p_target);
1188 * skip rest of while loop
1190 targetlist = lnext(targetlist);
1195 * Target item is relation.*, expand the table
1196 * (eg. SELECT emp.*, dname FROM emp, dept)
1198 attrname = strVal(lfirst(att->attrs));
1199 if (att->attrs!=NIL && !strcmp(attrname,"*")) {
1200 /* tail_p_target is the target list we're building in the while
1201 * loop. Make sure we fix it after appending more nodes.
1203 if (tail_p_target == NIL)
1204 p_target = tail_p_target = expandAll(pstate, att->relname,
1205 att->relname, &pstate->p_last_resno);
1207 lnext(tail_p_target) =
1208 expandAll(pstate, att->relname, att->relname,
1209 &pstate->p_last_resno);
1210 while(lnext(tail_p_target)!=NIL)
1211 /* make sure we point to the last target entry */
1212 tail_p_target = lnext(tail_p_target);
1214 * skip the rest of the while loop
1216 targetlist = lnext(targetlist);
1222 * Target item is fully specified: ie. relation.attribute
1224 result = handleNestedDots(pstate, att, &pstate->p_last_resno);
1225 handleTargetColname(pstate, &res->name, att->relname, attrname);
1226 if (att->indirection != NIL) {
1227 List *ilist = att->indirection;
1228 while (ilist!=NIL) {
1229 A_Indices *ind = lfirst(ilist);
1230 ind->lidx = transformExpr(pstate, ind->lidx, EXPR_COLUMN_FIRST);
1231 ind->uidx = transformExpr(pstate, ind->uidx, EXPR_COLUMN_FIRST);
1232 ilist = lnext(ilist);
1234 result = (Node*)make_array_ref(result, att->indirection);
1236 type_id = exprType(result);
1237 type_len = tlen(get_id_type(type_id));
1238 /* move to last entry */
1239 while(lnext(attrs)!=NIL)
1241 resname = (res->name) ? res->name : strVal(lfirst(attrs));
1242 resnode = makeResdom((AttrNumber)pstate->p_last_resno++,
1249 tent->resdom = resnode;
1250 tent->expr = result;
1254 /* internal error */
1256 "internal error: do not know how to transform targetlist");
1260 if (p_target == NIL) {
1261 p_target = tail_p_target = lcons(tent, NIL);
1263 lnext(tail_p_target) = lcons(tent, NIL);
1264 tail_p_target = lnext(tail_p_target);
1266 targetlist = lnext(targetlist);
1274 * make_targetlist_expr -
1275 * make a TargetEntry from an expression
1277 * arrayRef is a list of transformed A_Indices
1279 static TargetEntry *
1280 make_targetlist_expr(ParseState *pstate,
1285 Oid type_id, attrtype;
1286 int type_len, attrlen;
1294 elog(WARN, "make_targetlist_expr: invalid use of NULL expression");
1296 type_id = exprType(expr);
1297 if (type_id == InvalidOid) {
1300 type_len = tlen(get_id_type(type_id));
1302 /* I have no idea what the following does! */
1303 /* It appears to process target columns that will be receiving results */
1304 if (pstate->p_is_insert||pstate->p_is_update) {
1306 * append or replace query --
1307 * append, replace work only on one relation,
1308 * so multiple occurence of same resdomno is bogus
1310 rd = pstate->p_target_relation;
1312 resdomno = varattno(rd,colname);
1313 attrisset = varisset(rd,colname);
1314 attrtype = att_typeid(rd,resdomno);
1315 if ((arrayRef != NIL) && (lfirst(arrayRef) == NIL))
1316 attrtype = GetArrayElementType(attrtype);
1317 if (attrtype==BPCHAROID || attrtype==VARCHAROID) {
1318 attrlen = rd->rd_att->attrs[resdomno-1]->attlen;
1320 attrlen = tlen(get_id_type(attrtype));
1323 if(Input_is_string && Typecast_ok){
1325 if (type_id == typeid(type("unknown"))){
1326 val = (Datum)textout((struct varlena *)
1327 ((Const)lnext(expr))->constvalue);
1329 val = ((Const)lnext(expr))->constvalue;
1332 lnext(expr) = makeConst(attrtype,
1343 (Datum)fmgr(typeid_get_retinfunc(attrtype),
1344 val,get_typelem(attrtype),-1),
1346 true /* Maybe correct-- 80% chance */,
1347 false, /* is not a set */
1350 } else if((Typecast_ok) && (attrtype != type_id)){
1352 parser_typecast2(expr, get_id_type(attrtype));
1354 if (attrtype != type_id) {
1355 if ((attrtype == INT2OID) && (type_id == INT4OID))
1356 lfirst(expr) = lispInteger (INT2OID); /* handle CASHOID too*/
1357 else if ((attrtype == FLOAT4OID) && (type_id == FLOAT8OID))
1358 lfirst(expr) = lispInteger (FLOAT4OID);
1360 elog(WARN, "unequal type in tlist : %s \n", colname);
1363 Input_is_string = false;
1364 Input_is_integer = false;
1368 if (attrtype != type_id) {
1369 if (IsA(expr,Const)) {
1370 /* try to cast the constant */
1371 if (arrayRef && !(((A_Indices *)lfirst(arrayRef))->lidx)) {
1372 /* updating a single item */
1373 Oid typelem = get_typelem(attrtype);
1374 expr = (Node*)parser_typecast2(expr,
1376 get_id_type(typelem),
1379 expr = (Node*)parser_typecast2(expr,
1381 get_id_type(attrtype),
1384 /* currently, we can't handle casting of expressions */
1385 elog(WARN, "parser: attribute '%s' is of type '%s' but expression is of type '%s'",
1387 get_id_typname(attrtype),
1388 get_id_typname(type_id));
1392 if (arrayRef != NIL) {
1394 Attr *att = makeNode(Attr);
1395 List *ar = arrayRef;
1396 List *upperIndexpr = NIL;
1397 List *lowerIndexpr = NIL;
1399 att->relname = pstrdup(RelationGetRelationName(rd)->data);
1400 att->attrs = lcons(makeString(colname), NIL);
1401 target_expr = (Expr*)handleNestedDots(pstate, att,
1402 &pstate->p_last_resno);
1404 A_Indices *ind = lfirst(ar);
1405 if (lowerIndexpr || (!upperIndexpr && ind->lidx)) {
1406 /* XXX assume all lowerIndexpr is non-null in
1409 lowerIndexpr = lappend(lowerIndexpr, ind->lidx);
1411 upperIndexpr = lappend(upperIndexpr, ind->uidx);
1415 expr = (Node*)make_array_set(target_expr,
1419 attrtype = att_typeid(rd,resdomno);
1420 attrlen = tlen(get_id_type(attrtype));
1423 resdomno = pstate->p_last_resno++;
1427 tent = makeNode(TargetEntry);
1429 resnode = makeResdom((AttrNumber)resdomno,
1437 tent->resdom = resnode;
1444 /*****************************************************************************
1448 *****************************************************************************/
1451 * transformWhereClause -
1452 * transforms the qualification and make sure it is of type Boolean
1456 transformWhereClause(ParseState *pstate, Node *a_expr)
1461 return (Node *)NULL; /* no qualifiers */
1463 inWhereClause = true;
1464 qual = transformExpr(pstate, a_expr, EXPR_COLUMN_FIRST);
1465 inWhereClause = false;
1466 if (exprType(qual) != BOOLOID) {
1468 "where clause must return type bool, not %s",
1469 tname(get_id_type(exprType(qual))));
1474 /*****************************************************************************
1478 *****************************************************************************/
1481 * find_targetlist_entry -
1482 * returns the Resdom in the target list matching the specified varname
1486 static TargetEntry *
1487 find_targetlist_entry(ParseState *pstate, SortGroupBy *sortgroupby, List *tlist)
1490 int real_rtable_pos = 0, target_pos = 0;
1491 TargetEntry *target_result = NULL;
1493 if(sortgroupby->range)
1494 real_rtable_pos = refnameRangeTablePosn(pstate->p_rtable,
1495 sortgroupby->range);
1498 TargetEntry *target = (TargetEntry *)lfirst(i);
1499 Resdom *resnode = target->resdom;
1500 Var *var = (Var *)target->expr;
1501 char *resname = resnode->resname;
1502 int test_rtable_pos = var->varno;
1505 printf("find_targetlist_entry- target name is %s, position %d, resno %d\n",
1506 (sortgroupby->name? sortgroupby->name: "(null)"), target_pos+1, sortgroupby->resno);
1509 if (!sortgroupby->name) {
1510 if (sortgroupby->resno == ++target_pos) {
1511 target_result = target;
1516 if (!strcmp(resname, sortgroupby->name)) {
1517 if(sortgroupby->range) {
1518 if(real_rtable_pos == test_rtable_pos) {
1519 if (target_result != NULL)
1520 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1521 else target_result = target;
1525 if (target_result != NULL)
1526 elog(WARN, "Order/Group By %s is ambiguous", sortgroupby->name);
1527 else target_result = target;
1532 return target_result;
1536 any_ordering_op(int restype)
1541 order_op = oper("<",restype,restype,false);
1542 order_opid = oprid(order_op);
1548 * transformGroupClause -
1549 * transform a Group By clause
1553 transformGroupClause(ParseState *pstate, List *grouplist, List *targetlist)
1555 List *glist = NIL, *gl = NIL;
1557 while (grouplist != NIL) {
1558 GroupClause *grpcl = makeNode(GroupClause);
1559 TargetEntry *restarget;
1562 restarget = find_targetlist_entry(pstate, lfirst(grouplist), targetlist);
1564 if (restarget == NULL)
1565 elog(WARN,"The field being grouped by must appear in the target list");
1567 grpcl->entry = restarget;
1568 resdom = restarget->resdom;
1569 grpcl->grpOpoid = oprid(oper("<",
1571 resdom->restype,false));
1573 gl = glist = lcons(grpcl, NIL);
1575 lnext(gl) = lcons(grpcl, NIL);
1578 grouplist = lnext(grouplist);
1585 * transformSortClause -
1586 * transform an Order By clause
1590 transformSortClause(ParseState *pstate,
1591 List *orderlist, List *targetlist,
1594 List *sortlist = NIL;
1597 while(orderlist != NIL) {
1598 SortGroupBy *sortby = lfirst(orderlist);
1599 SortClause *sortcl = makeNode(SortClause);
1600 TargetEntry *restarget;
1603 restarget = find_targetlist_entry(pstate, sortby, targetlist);
1604 if (restarget == NULL)
1605 elog(WARN,"The field being ordered by must appear in the target list");
1607 sortcl->resdom = resdom = restarget->resdom;
1608 sortcl->opoid = oprid(oper(sortby->useOp,
1610 resdom->restype,false));
1611 if (sortlist == NIL) {
1612 s = sortlist = lcons(sortcl, NIL);
1614 lnext(s) = lcons(sortcl, NIL);
1617 orderlist = lnext(orderlist);
1621 if (uniqueFlag[0] == '*') {
1622 /* concatenate all elements from target list
1623 that are not already in the sortby list */
1624 foreach (i,targetlist) {
1625 TargetEntry *tlelt = (TargetEntry *)lfirst(i);
1629 SortClause *sortcl = lfirst(s);
1630 if (sortcl->resdom==tlelt->resdom)
1635 /* not a member of the sortclauses yet */
1636 SortClause *sortcl = makeNode(SortClause);
1638 sortcl->resdom = tlelt->resdom;
1639 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1641 sortlist = lappend(sortlist, sortcl);
1646 TargetEntry *tlelt = NULL;
1647 char* uniqueAttrName = uniqueFlag;
1649 /* only create sort clause with the specified unique attribute */
1650 foreach (i, targetlist) {
1651 tlelt = (TargetEntry*)lfirst(i);
1652 if (strcmp(tlelt->resdom->resname, uniqueAttrName) == 0)
1656 elog(WARN, "The field specified in the UNIQUE ON clause is not in the targetlist");
1659 foreach (s, sortlist) {
1660 SortClause *sortcl = lfirst(s);
1661 if (sortcl->resdom == tlelt->resdom)
1665 /* not a member of the sortclauses yet */
1666 SortClause *sortcl = makeNode(SortClause);
1668 sortcl->resdom = tlelt->resdom;
1669 sortcl->opoid = any_ordering_op(tlelt->resdom->restype);
1671 sortlist = lappend(sortlist, sortcl);
1681 ** HandleNestedDots --
1682 ** Given a nested dot expression (i.e. (relation func ... attr), build up
1683 ** a tree with of Iter and Func nodes.
1686 handleNestedDots(ParseState *pstate, Attr *attr, int *curr_resno)
1689 Node *retval = NULL;
1691 if (attr->paramNo != NULL) {
1692 Param *param = (Param *)transformExpr(pstate, (Node*)attr->paramNo, EXPR_RELATION_FIRST);
1695 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1699 Ident *ident = makeNode(Ident);
1701 ident->name = attr->relname;
1702 ident->isRel = TRUE;
1704 ParseFunc(pstate, strVal(lfirst(attr->attrs)),
1709 foreach (mutator_iter, lnext(attr->attrs)) {
1710 retval = ParseFunc(pstate,strVal(lfirst(mutator_iter)),
1719 ** make_arguments --
1720 ** Given the number and types of arguments to a function, and the
1721 ** actual arguments and argument types, do the necessary typecasting.
1724 make_arguments(int nargs,
1727 Oid *function_typeids)
1730 * there are two ways an input typeid can differ from a function typeid :
1731 * either the input type inherits the function type, so no typecasting is
1732 * necessary, or the input type can be typecast into the function type.
1733 * right now, we only typecast unknowns, and that is all we check for.
1736 List *current_fargs;
1739 for (i=0, current_fargs = fargs;
1741 i++, current_fargs = lnext(current_fargs)) {
1743 if (input_typeids[i] == UNKNOWNOID && function_typeids[i] != InvalidOid) {
1744 lfirst(current_fargs) =
1745 parser_typecast2(lfirst(current_fargs),
1747 get_id_type(function_typeids[i]),
1755 ** Build a tlist that says which attribute to project to.
1756 ** This routine is called by ParseFunc() to set up a target list
1757 ** on a tuple parameter or return value. Due to a bug in 4.0,
1758 ** it's not possible to refer to system attributes in this case.
1761 setup_tlist(char *attname, Oid relid)
1769 attno = get_attnum(relid, attname);
1771 elog(WARN, "cannot reference attribute %s of tuple params/return values for functions", attname);
1773 typeid = find_atttype(relid, attname);
1774 resnode = makeResdom(1,
1776 tlen(get_id_type(typeid)),
1777 get_attname(relid, attno),
1781 varnode = makeVar(-1, attno, typeid, -1, attno);
1783 tle = makeNode(TargetEntry);
1784 tle->resdom = resnode;
1785 tle->expr = (Node*)varnode;
1786 return (lcons(tle, NIL));
1790 ** setup_base_tlist --
1791 ** Build a tlist that extracts a base type from the tuple
1792 ** returned by the executor.
1795 setup_base_tlist(Oid typeid)
1801 resnode = makeResdom(1,
1803 tlen(get_id_type(typeid)),
1808 varnode = makeVar(-1, 1, typeid, -1, 1);
1809 tle = makeNode(TargetEntry);
1810 tle->resdom = resnode;
1811 tle->expr = (Node*)varnode;
1813 return (lcons(tle, NIL));
1817 * ParseComplexProjection -
1818 * handles function calls with a single argument that is of complex type.
1819 * This routine returns NULL if it can't handle the projection (eg. sets).
1822 ParseComplexProjection(ParseState *pstate,
1834 switch (nodeTag(first_arg)) {
1840 iter = (Iter*)first_arg;
1841 func = (Func *)((Expr*)iter->iterexpr)->oper;
1842 argtype = funcid_get_rettype(func->funcid);
1843 argrelid = typeid_get_relid(argtype);
1845 ((attnum = get_attnum(argrelid, funcname))
1846 != InvalidAttrNumber)) {
1848 /* the argument is a function returning a tuple, so funcname
1849 may be a projection */
1851 /* add a tlist to the func node and return the Iter */
1852 rd = heap_openr(tname(get_id_type(argtype)));
1853 if (RelationIsValid(rd)) {
1854 relid = RelationGetRelationId(rd);
1855 relname = RelationGetRelationName(rd);
1858 if (RelationIsValid(rd)) {
1860 setup_tlist(funcname, argrelid);
1861 iter->itertype = att_typeid(rd,attnum);
1862 return ((Node*)iter);
1865 "Function %s has bad returntype %d",
1877 * The argument is a set, so this is either a projection
1878 * or a function call on this set.
1885 Expr *expr = (Expr*)first_arg;
1888 if (expr->opType != FUNC_EXPR)
1891 funcnode= (Func *) expr->oper;
1892 argtype = funcid_get_rettype(funcnode->funcid);
1893 argrelid = typeid_get_relid(argtype);
1895 * the argument is a function returning a tuple, so funcname
1896 * may be a projection
1899 (attnum = get_attnum(argrelid, funcname))
1900 != InvalidAttrNumber) {
1902 /* add a tlist to the func node */
1903 rd = heap_openr(tname(get_id_type(argtype)));
1904 if (RelationIsValid(rd)) {
1905 relid = RelationGetRelationId(rd);
1906 relname = RelationGetRelationName(rd);
1909 if (RelationIsValid(rd)) {
1912 funcnode->func_tlist =
1913 setup_tlist(funcname, argrelid);
1914 funcnode->functype = att_typeid(rd,attnum);
1916 newexpr = makeNode(Expr);
1917 newexpr->typeOid = funcnode->functype;
1918 newexpr->opType = FUNC_EXPR;
1919 newexpr->oper = (Node *)funcnode;
1920 newexpr->args = lcons(first_arg, NIL);
1922 return ((Node*)newexpr);
1927 elog(WARN, "Function %s has bad returntype %d",
1933 Param *param = (Param*)first_arg;
1935 * If the Param is a complex type, this could be a projection
1937 rd = heap_openr(tname(get_id_type(param->paramtype)));
1938 if (RelationIsValid(rd)) {
1939 relid = RelationGetRelationId(rd);
1940 relname = RelationGetRelationName(rd);
1943 if (RelationIsValid(rd) &&
1944 (attnum = get_attnum(relid, funcname))
1945 != InvalidAttrNumber) {
1947 param->paramtype = att_typeid(rd, attnum);
1948 param->param_tlist = setup_tlist(funcname, relid);
1949 return ((Node*)param);
1961 ParseFunc(ParseState *pstate, char *funcname, List *fargs, int *curr_resno)
1963 Oid rettype = (Oid)0;
1964 Oid argrelid = (Oid)0;
1965 Oid funcid = (Oid)0;
1967 Node *first_arg= NULL;
1968 char *relname = NULL;
1969 char *refname = NULL;
1975 Oid *true_oid_array;
1979 bool attisset = false;
1984 first_arg = lfirst(fargs);
1985 if (first_arg == NULL)
1986 elog (WARN,"function %s does not allow NULL input",funcname);
1990 ** check for projection methods: if function takes one argument, and
1991 ** that argument is a relation, param, or PQ function returning a complex
1992 ** type, then the function could be a projection.
1994 if (length(fargs) == 1) {
1996 if (nodeTag(first_arg)==T_Ident && ((Ident*)first_arg)->isRel) {
1998 Ident *ident = (Ident*)first_arg;
2001 * first arg is a relation. This could be a projection.
2003 refname = ident->name;
2005 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2007 rte = addRangeTableEntry(pstate, refname, refname, FALSE, FALSE,NULL);
2009 relname = rte->relname;
2012 /* If the attr isn't a set, just make a var for it. If
2013 * it is a set, treat it like a function and drop through.
2015 if (get_attnum(relid, funcname) != InvalidAttrNumber) {
2019 ((Node*)make_var(pstate,
2024 /* drop through - attr is a set */
2027 } else if (ISCOMPLEX(exprType(first_arg))) {
2029 * Attempt to handle projection of a complex argument. If
2030 * ParseComplexProjection can't handle the projection, we
2031 * have to keep going.
2033 retval = ParseComplexProjection(pstate,
2038 toid = exprType(first_arg);
2039 rd = heap_openr(tname(get_id_type(toid)));
2040 if (RelationIsValid(rd)) {
2041 relname = RelationGetRelationName(rd)->data;
2045 "Type %s is not a relation type",
2046 tname(get_id_type(toid)));
2047 argrelid = typeid_get_relid(toid);
2048 /* A projection contains either an attribute name or the
2051 if ((get_attnum(argrelid, funcname) == InvalidAttrNumber)
2052 && strcmp(funcname, "*")) {
2053 elog(WARN, "Functions on sets are not yet supported");
2061 * Parsing aggregates.
2064 /* the aggregate count is a special case,
2065 ignore its base type. Treat it as zero */
2066 if (strcmp(funcname, "count") == 0)
2069 basetype = exprType(lfirst(fargs));
2070 if (SearchSysCacheTuple(AGGNAME,
2071 PointerGetDatum(funcname),
2072 ObjectIdGetDatum(basetype),
2074 Aggreg *aggreg = ParseAgg(funcname, basetype, lfirst(fargs));
2076 AddAggToParseState(pstate, aggreg);
2077 return (Node*)aggreg;
2084 ** If we dropped through to here it's really a function (or a set, which
2085 ** is implemented as a function.)
2086 ** extract arg type info and transform relation name arguments into
2087 ** varnodes of the appropriate form.
2089 memset(&oid_array[0], 0, 8 * sizeof(Oid));
2092 foreach ( i , fargs ) {
2095 Node *pair = lfirst(i);
2097 if (nodeTag(pair)==T_Ident && ((Ident*)pair)->isRel) {
2101 refname = ((Ident*)pair)->name;
2103 rte = refnameRangeTableEntry(pstate->p_rtable, refname);
2105 rte = addRangeTableEntry(pstate, refname, refname,
2106 FALSE, FALSE, NULL);
2107 relname = rte->relname;
2109 vnum = refnameRangeTablePosn (pstate->p_rtable, rte->refname);
2112 * for func(relname), the param to the function
2113 * is the tuple under consideration. we build a special
2114 * VarNode to reflect this -- it has varno set to the
2115 * correct range table entry, but has varattno == 0 to
2116 * signal that the whole tuple is the argument.
2118 toid = typeid(type(relname));
2119 /* replace it in the arg list */
2121 makeVar(vnum, 0, toid, vnum, 0);
2122 }else if (!attisset) { /* set functions don't have parameters */
2124 /* any functiona args which are typed "unknown", but aren't
2125 constants, we don't know what to do with, because we
2126 can't cast them - jolly*/
2127 if (exprType(pair) == UNKNOWNOID &&
2130 elog(WARN, "ParseFunc: no function named %s that takes in an unknown type as argument #%d", funcname, nargs);
2133 toid = exprType(pair);
2136 oid_array[nargs++] = toid;
2140 * func_get_detail looks up the function in the catalogs, does
2141 * disambiguation for polymorphic functions, handles inheritance,
2142 * and returns the funcid and type and set or singleton status of
2143 * the function's return value. it also returns the true argument
2144 * types to the function. if func_get_detail returns true,
2145 * the function exists. otherwise, there was an error.
2147 if (attisset) { /* we know all of these fields already */
2148 /* We create a funcnode with a placeholder function SetEval.
2149 * SetEval() never actually gets executed. When the function
2150 * evaluation routines see it, they use the funcid projected
2151 * out from the relation as the actual function to call.
2152 * Example: retrieve (emp.mgr.name)
2153 * The plan for this will scan the emp relation, projecting
2154 * out the mgr attribute, which is a funcid. This function
2155 * is then called (instead of SetEval) and "name" is projected
2158 funcid = SetEvalRegProcedure;
2161 true_oid_array = oid_array;
2164 exists = func_get_detail(funcname, nargs, oid_array, &funcid,
2165 &rettype, &retset, &true_oid_array);
2169 elog(WARN, "no such attribute or function %s", funcname);
2172 funcnode = makeNode(Func);
2173 funcnode->funcid = funcid;
2174 funcnode->functype = rettype;
2175 funcnode->funcisindex = false;
2176 funcnode->funcsize = 0;
2177 funcnode->func_fcache = NULL;
2178 funcnode->func_tlist = NIL;
2179 funcnode->func_planlist = NIL;
2181 /* perform the necessary typecasting */
2182 make_arguments(nargs, fargs, oid_array, true_oid_array);
2185 * for functions returning base types, we want to project out the
2186 * return value. set up a target list to do that. the executor
2187 * will ignore these for c functions, and do the right thing for
2188 * postquel functions.
2191 if (typeid_get_relid(rettype) == InvalidOid)
2192 funcnode->func_tlist = setup_base_tlist(rettype);
2194 /* For sets, we want to make a targetlist to project out this
2195 * attribute of the set tuples.
2198 if (!strcmp(funcname, "*")) {
2199 funcnode->func_tlist =
2200 expandAll(pstate, relname, refname, curr_resno);
2202 funcnode->func_tlist = setup_tlist(funcname,argrelid);
2203 rettype = find_atttype(argrelid, funcname);
2208 * Sequence handling.
2210 if ( funcid == SeqNextValueRegProcedure ||
2211 funcid == SeqCurrValueRegProcedure )
2215 int32 aclcheck_result = -1;
2217 Assert ( length(fargs) == 1 );
2218 seq = (Const*)lfirst(fargs);
2219 if ( ! IsA ((Node*)seq, Const) )
2220 elog (WARN, "%s: only constant sequence names are acceptable", funcname);
2221 seqrel = textout ((struct varlena *) (seq->constvalue));
2223 if ( ( aclcheck_result = pg_aclcheck (seqrel, GetPgUserName(),
2224 ((funcid == SeqNextValueRegProcedure) ? ACL_WR : ACL_RD)) )
2226 elog (WARN, "%s.%s: %s",
2227 seqrel, funcname, aclcheck_error_strings[aclcheck_result]);
2231 if ( funcid == SeqNextValueRegProcedure && inWhereClause )
2232 elog (WARN, "nextval of a sequence in WHERE disallowed");
2235 expr = makeNode(Expr);
2236 expr->typeOid = rettype;
2237 expr->opType = FUNC_EXPR;
2238 expr->oper = (Node *)funcnode;
2240 retval = (Node*)expr;
2243 * if the function returns a set of values, then we need to iterate
2244 * over all the returned values in the executor, so we stick an
2245 * iter node here. if it returns a singleton, then we don't need
2250 Iter *iter = makeNode(Iter);
2251 iter->itertype = rettype;
2252 iter->iterexpr = retval;
2253 retval = (Node*)iter;
2259 /*****************************************************************************
2261 *****************************************************************************/
2264 * AddAggToParseState -
2265 * add the aggregate to the list of unique aggregates in pstate.
2267 * SIDE EFFECT: aggno in target list entry will be modified
2270 AddAggToParseState(ParseState *pstate, Aggreg *aggreg)
2276 * see if we have the aggregate already (we only need to record
2277 * the aggregate once)
2280 foreach(ag, pstate->p_aggs) {
2281 Aggreg *a = lfirst(ag);
2283 if (!strcmp(a->aggname, aggreg->aggname) &&
2284 equal(a->target, aggreg->target)) {
2286 /* fill in the aggno and we're done */
2293 /* not found, new aggregate */
2296 pstate->p_aggs = lappend(pstate->p_aggs, aggreg);
2301 * finalizeAggregates -
2302 * fill in qry_aggs from pstate. Also checks to make sure that aggregates
2303 * are used in the proper place.
2306 finalizeAggregates(ParseState *pstate, Query *qry)
2311 parseCheckAggregates(pstate, qry);
2313 qry->qry_numAgg = pstate->p_numAgg;
2315 (Aggreg **)palloc(sizeof(Aggreg *) * qry->qry_numAgg);
2317 foreach(l, pstate->p_aggs)
2318 qry->qry_aggs[i++] = (Aggreg*)lfirst(l);
2322 * contain_agg_clause--
2323 * Recursively find aggreg nodes from a clause.
2325 * Returns true if any aggregate found.
2328 contain_agg_clause(Node *clause)
2332 else if (IsA(clause,Aggreg))
2334 else if (IsA(clause,Iter))
2335 return contain_agg_clause(((Iter*)clause)->iterexpr);
2336 else if (single_node(clause))
2338 else if (or_clause(clause)) {
2341 foreach (temp, ((Expr*)clause)->args)
2342 if (contain_agg_clause(lfirst(temp)))
2345 } else if (is_funcclause (clause)) {
2348 foreach(temp, ((Expr *)clause)->args)
2349 if (contain_agg_clause(lfirst(temp)))
2352 } else if (IsA(clause,ArrayRef)) {
2355 foreach(temp, ((ArrayRef*)clause)->refupperindexpr)
2356 if (contain_agg_clause(lfirst(temp)))
2358 foreach(temp, ((ArrayRef*)clause)->reflowerindexpr)
2359 if (contain_agg_clause(lfirst(temp)))
2361 if (contain_agg_clause(((ArrayRef*)clause)->refexpr))
2363 if (contain_agg_clause(((ArrayRef*)clause)->refassgnexpr))
2366 } else if (not_clause(clause))
2367 return contain_agg_clause((Node*)get_notclausearg((Expr*)clause));
2368 else if (is_opclause(clause))
2369 return (contain_agg_clause((Node*)get_leftop((Expr*)clause)) ||
2370 contain_agg_clause((Node*)get_rightop((Expr*)clause)));
2376 * exprIsAggOrGroupCol -
2377 * returns true if the expression does not contain non-group columns.
2380 exprIsAggOrGroupCol(Node *expr, List *groupClause)
2384 if ( expr == NULL || IsA (expr, Const) ||
2385 IsA (expr, Param) || IsA (expr, Aggreg) )
2388 foreach (gl, groupClause)
2390 GroupClause *grpcl = lfirst(gl);
2392 if ( equal (expr, grpcl->entry->expr) )
2396 if ( IsA (expr, Expr) )
2400 foreach (temp, ((Expr*)expr)->args)
2401 if (!exprIsAggOrGroupCol(lfirst(temp),groupClause))
2410 * tleIsAggOrGroupCol -
2411 * returns true if the TargetEntry is Agg or GroupCol.
2414 tleIsAggOrGroupCol(TargetEntry *tle, List *groupClause)
2416 Node *expr = tle->expr;
2419 if ( expr == NULL || IsA (expr, Const) || IsA (expr, Param) )
2422 foreach (gl, groupClause)
2424 GroupClause *grpcl = lfirst(gl);
2426 if ( tle->resdom->resno == grpcl->entry->resdom->resno )
2428 if ( contain_agg_clause ((Node*) expr) )
2429 elog (WARN, "parser: aggregates not allowed in GROUP BY clause");
2434 if ( IsA (expr, Aggreg) )
2437 if ( IsA (expr, Expr) )
2441 foreach (temp, ((Expr*)expr)->args)
2442 if (!exprIsAggOrGroupCol(lfirst(temp),groupClause))
2451 * parseCheckAggregates -
2452 * this should really be done earlier but the current grammar
2453 * cannot differentiate functions from aggregates. So we have do check
2454 * here when the target list and the qualifications are finalized.
2457 parseCheckAggregates(ParseState *pstate, Query *qry)
2460 Assert(pstate->p_numAgg > 0);
2463 * aggregates never appear in WHERE clauses. (we have to check where
2464 * clause first because if there is an aggregate, the check for
2465 * non-group column in target list may fail.)
2467 if (contain_agg_clause(qry->qual))
2468 elog(WARN, "parser: aggregates not allowed in WHERE clause");
2471 * the target list can only contain aggregates, group columns and
2472 * functions thereof.
2474 foreach (tl, qry->targetList) {
2475 TargetEntry *tle = lfirst(tl);
2476 if (!tleIsAggOrGroupCol(tle, qry->groupClause))
2478 "parser: illegal use of aggregates or non-group column in target list");
2482 * the expression specified in the HAVING clause has the same restriction
2483 * as those in the target list.
2486 * Need to change here when we get HAVING works. Currently
2487 * qry->havingQual is NULL. - vadim 04/05/97
2488 if (!exprIsAggOrGroupCol(qry->havingQual, qry->groupClause))
2490 "parser: illegal use of aggregates or non-group column in HAVING clause");