1 /*-------------------------------------------------------------------------
4 * transform the parse tree into a query tree
6 * Copyright (c) 1994, Regents of the University of California
8 * $Id: analyze.c,v 1.119 1999/09/18 19:07:12 tgl Exp $
10 *-------------------------------------------------------------------------
15 #include "access/heapam.h"
16 #include "catalog/pg_type.h"
17 #include "nodes/makefuncs.h"
19 #include "parser/analyze.h"
20 #include "parser/parse_agg.h"
21 #include "parser/parse_clause.h"
22 #include "parser/parse_relation.h"
23 #include "parser/parse_target.h"
24 #include "utils/builtins.h"
26 static Query *transformStmt(ParseState *pstate, Node *stmt);
27 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
28 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
29 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
30 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
31 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
32 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
33 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
34 static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
35 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
37 static void transformForUpdate(Query *qry, List *forUpdate);
38 void CheckSelectForUpdate(Query *qry);
40 /* kluge to return extra info from transformCreateStmt() */
41 static List *extras_before;
42 static List *extras_after;
47 * analyze a list of parse trees and transform them if necessary.
49 * Returns a list of transformed parse trees. Optimizable statements are
50 * all transformed to Query while the rest stays the same.
54 parse_analyze(List *pl, ParseState *parentParseState)
62 extras_before = extras_after = NIL;
63 pstate = make_parsestate(parentParseState);
65 parsetree = transformStmt(pstate, lfirst(pl));
66 if (pstate->p_target_relation != NULL)
67 heap_close(pstate->p_target_relation, AccessShareLock);
68 pstate->p_target_relation = NULL;
69 pstate->p_target_rangetblentry = NULL;
71 while (extras_before != NIL)
73 result = lappend(result,
74 transformStmt(pstate, lfirst(extras_before)));
75 if (pstate->p_target_relation != NULL)
76 heap_close(pstate->p_target_relation, AccessShareLock);
77 pstate->p_target_relation = NULL;
78 pstate->p_target_rangetblentry = NULL;
79 extras_before = lnext(extras_before);
82 result = lappend(result, parsetree);
84 while (extras_after != NIL)
86 result = lappend(result,
87 transformStmt(pstate, lfirst(extras_after)));
88 if (pstate->p_target_relation != NULL)
89 heap_close(pstate->p_target_relation, AccessShareLock);
90 pstate->p_target_relation = NULL;
91 pstate->p_target_rangetblentry = NULL;
92 extras_after = lnext(extras_after);
104 * transform a Parse tree. If it is an optimizable statement, turn it
108 transformStmt(ParseState *pstate, Node *parseTree)
110 Query *result = NULL;
112 switch (nodeTag(parseTree))
114 /*------------------------
115 * Non-optimizable statements
116 *------------------------
119 result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
123 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
127 result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
131 result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
136 ViewStmt *n = (ViewStmt *) parseTree;
138 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
139 result = makeNode(Query);
140 result->commandType = CMD_UTILITY;
141 result->utilityStmt = (Node *) n;
147 MemoryContext oldcontext;
150 * make sure that this Query is allocated in TopMemory
151 * context because vacuum spans transactions and we don't
152 * want to lose the vacuum Query due to end-of-transaction
155 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
156 result = makeNode(Query);
157 result->commandType = CMD_UTILITY;
158 result->utilityStmt = (Node *) parseTree;
159 MemoryContextSwitchTo(oldcontext);
165 ExplainStmt *n = (ExplainStmt *) parseTree;
167 result = makeNode(Query);
168 result->commandType = CMD_UTILITY;
169 n->query = transformStmt(pstate, (Node *) n->query);
170 result->utilityStmt = (Node *) parseTree;
174 /*------------------------
175 * Optimizable statements
176 *------------------------
179 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
183 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
187 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
191 if (!((SelectStmt *) parseTree)->portalname)
193 result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
194 result->limitOffset = ((SelectStmt *) parseTree)->limitOffset;
195 result->limitCount = ((SelectStmt *) parseTree)->limitCount;
198 result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
204 * other statments don't require any transformation-- just
205 * return the original parsetree, yea!
207 result = makeNode(Query);
208 result->commandType = CMD_UTILITY;
209 result->utilityStmt = (Node *) parseTree;
216 * transformDeleteStmt -
217 * transforms a Delete Statement
220 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
222 Query *qry = makeNode(Query);
224 qry->commandType = CMD_DELETE;
226 /* set up a range table */
227 makeRangeTable(pstate, NULL, NULL);
228 setTargetTable(pstate, stmt->relname);
230 qry->uniqueFlag = NULL;
232 /* fix where clause */
233 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
234 qry->hasSubLinks = pstate->p_hasSubLinks;
236 qry->rtable = pstate->p_rtable;
237 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
239 qry->hasAggs = pstate->p_hasAggs;
240 if (pstate->p_hasAggs)
241 parseCheckAggregates(pstate, qry);
243 return (Query *) qry;
247 * transformInsertStmt -
248 * transform an Insert Statement
251 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
253 Query *qry = makeNode(Query);
259 qry->commandType = CMD_INSERT;
260 pstate->p_is_insert = true;
263 * Initial processing steps are just like SELECT, which should not
264 * be surprising, since we may be handling an INSERT ... SELECT.
265 * It is important that we finish processing all the SELECT subclauses
266 * before we start doing any INSERT-specific processing; otherwise
267 * the behavior of SELECT within INSERT might be different from a
268 * stand-alone SELECT. (Indeed, Postgres up through 6.5 had bugs of
269 * just that nature...)
273 /* set up a range table --- note INSERT target is not in it yet */
274 makeRangeTable(pstate, stmt->fromClause, &fromQual);
276 qry->uniqueFlag = stmt->unique;
278 qry->targetList = transformTargetList(pstate, stmt->targetList);
280 qry->qual = transformWhereClause(pstate, stmt->whereClause, fromQual);
282 /* Initial processing of HAVING clause is just like WHERE clause.
283 * Additional work will be done in optimizer/plan/planner.c.
285 qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
287 qry->groupClause = transformGroupClause(pstate,
291 /* An InsertStmt has no sortClause, but we still call
292 * transformSortClause because it also handles uniqueFlag.
294 qry->sortClause = transformSortClause(pstate,
299 qry->hasSubLinks = pstate->p_hasSubLinks;
300 qry->hasAggs = pstate->p_hasAggs;
301 if (pstate->p_hasAggs || qry->groupClause)
302 parseCheckAggregates(pstate, qry);
305 * If there is a havingQual but there are no aggregates, then there is
306 * something wrong with the query because HAVING must contain
307 * aggregates in its expressions! Otherwise the query could have been
308 * formulated using the WHERE clause.
310 if (qry->havingQual && ! qry->hasAggs)
311 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
314 * The INSERT INTO ... SELECT ... could have a UNION in child, so
315 * unionClause may be false
317 qry->unionall = stmt->unionall;
320 * Just hand through the unionClause and intersectClause. We will
321 * handle it in the function Except_Intersect_Rewrite()
323 qry->unionClause = stmt->unionClause;
324 qry->intersectClause = stmt->intersectClause;
327 * Now we are done with SELECT-like processing, and can get on with
328 * transforming the target list to match the INSERT target columns.
330 * In particular, it's time to add the INSERT target to the rangetable.
331 * (We didn't want it there until now since it shouldn't be visible in
334 setTargetTable(pstate, stmt->relname);
336 /* now the range table will not change */
337 qry->rtable = pstate->p_rtable;
338 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
340 /* Prepare to assign non-conflicting resnos to resjunk attributes */
341 if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
342 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
344 /* Validate stmt->cols list, or build default list if no list given */
345 icolumns = makeTargetNames(pstate, stmt->cols);
347 /* Prepare non-junk columns for assignment to target table */
348 foreach(tl, qry->targetList)
350 TargetEntry *tle = (TargetEntry *) lfirst(tl);
351 Resdom *resnode = tle->resdom;
354 if (resnode->resjunk)
356 /* Resjunk nodes need no additional processing, but be sure they
357 * have names and resnos that do not match any target columns;
358 * else rewriter or planner might get confused.
360 resnode->resname = "?resjunk?";
361 resnode->resno = (AttrNumber) pstate->p_last_resno++;
365 elog(ERROR, "INSERT has more expressions than target columns");
366 id = (Ident *) lfirst(icolumns);
367 updateTargetListEntry(pstate, tle, id->name, id->indirection);
368 icolumns = lnext(icolumns);
372 * Add targetlist items to assign DEFAULT values to any columns that
373 * have defaults and were not assigned to by the user.
374 * XXX wouldn't it make more sense to do this further downstream,
375 * after the rule rewriter?
377 rd_att = pstate->p_target_relation->rd_att;
378 if (rd_att->constr && rd_att->constr->num_defval > 0)
380 Form_pg_attribute *att = rd_att->attrs;
381 AttrDefault *defval = rd_att->constr->defval;
382 int ndef = rd_att->constr->num_defval;
386 Form_pg_attribute thisatt = att[defval[ndef].adnum - 1];
389 foreach(tl, qry->targetList)
391 TargetEntry *tle = (TargetEntry *) lfirst(tl);
392 Resdom *resnode = tle->resdom;
394 if (resnode->resjunk)
395 continue; /* ignore resjunk nodes */
396 if (namestrcmp(&(thisatt->attname), resnode->resname) == 0)
399 if (tl != NIL) /* something given for this attr */
402 * No user-supplied value, so add a targetentry with DEFAULT expr
403 * and correct data for the target column.
405 te = makeTargetEntry(
406 makeResdom(defval[ndef].adnum,
409 pstrdup(nameout(&(thisatt->attname))),
411 stringToNode(defval[ndef].adbin));
412 qry->targetList = lappend(qry->targetList, te);
414 * Make sure the value is coerced to the target column type
415 * (might not be right type if it's not a constant!)
417 updateTargetListEntry(pstate, te, te->resdom->resname, NIL);
421 if (stmt->forUpdate != NULL)
422 transformForUpdate(qry, stmt->forUpdate);
424 return (Query *) qry;
430 * Create a name for an implicitly created index, sequence, constraint, etc.
432 * The parameters are: the original table name, the original field name, and
433 * a "type" string (such as "seq" or "pkey"). The field name and/or type
434 * can be NULL if not relevant.
436 * The result is a palloc'd string.
438 * The basic result we want is "name1_name2_type", omitting "_name2" or
439 * "_type" when those parameters are NULL. However, we must generate
440 * a name with less than NAMEDATALEN characters! So, we truncate one or
441 * both names if necessary to make a short-enough string. The type part
442 * is never truncated (so it had better be reasonably short).
444 * To reduce the probability of collisions, we might someday add more
445 * smarts to this routine, like including some "hash" characters computed
446 * from the truncated characters. Currently it seems best to keep it simple,
447 * so that the generated names are easily predictable by a person.
450 makeObjectName(char *name1, char *name2, char *typename)
453 int overhead = 0; /* chars needed for type and underscores */
454 int availchars; /* chars available for name(s) */
455 int name1chars; /* chars allocated to name1 */
456 int name2chars; /* chars allocated to name2 */
459 name1chars = strlen(name1);
462 name2chars = strlen(name2);
463 overhead++; /* allow for separating underscore */
468 overhead += strlen(typename) + 1;
470 availchars = NAMEDATALEN-1 - overhead;
472 /* If we must truncate, preferentially truncate the longer name.
473 * This logic could be expressed without a loop, but it's simple and
476 while (name1chars + name2chars > availchars)
478 if (name1chars > name2chars)
484 /* Now construct the string using the chosen lengths */
485 name = palloc(name1chars + name2chars + overhead + 1);
486 strncpy(name, name1, name1chars);
491 strncpy(name+ndx, name2, name2chars);
497 strcpy(name+ndx, typename);
506 CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
511 char typename[NAMEDATALEN];
513 /* The type name for makeObjectName is label, or labelN if that's
514 * necessary to prevent collisions among multiple indexes for the same
515 * table. Note there is no check for collisions with already-existing
516 * indexes; this ought to be rethought someday.
518 strcpy(typename, label);
522 iname = makeObjectName(table_name, column_name, typename);
524 foreach(ilist, indices)
526 IndexStmt *index = lfirst(ilist);
527 if (strcasecmp(iname, index->idxname) == 0)
530 /* ran through entire list? then no name conflict found so done */
534 /* the last one conflicted, so try a new name component */
536 sprintf(typename, "%s%d", label, ++pass);
543 * transformCreateStmt -
544 * transforms the "create table" statement
545 * SQL92 allows constraints to be scattered all over, so thumb through
546 * the columns and collect all constraints into one place.
547 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
548 * then expand those into multiple IndexStmt blocks.
549 * - thomas 1997-12-02
552 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
562 Constraint *constraint;
565 List *blist = NIL; /* "before list" of things to do before
566 * creating the table */
567 List *ilist = NIL; /* "index list" of things to do after
568 * creating the table */
574 q->commandType = CMD_UTILITY;
576 elements = stmt->tableElts;
577 constraints = stmt->constraints;
582 * Run through each primary element in the table creation clause
584 while (elements != NIL)
586 element = lfirst(elements);
587 switch (nodeTag(element))
590 column = (ColumnDef *) element;
591 columns = lappend(columns, column);
593 /* Special case SERIAL type? */
594 if (column->is_sequence)
598 CreateSeqStmt *sequence;
600 sname = makeObjectName(stmt->relname, column->colname,
602 constraint = makeNode(Constraint);
603 constraint->contype = CONSTR_DEFAULT;
604 constraint->name = sname;
605 cstring = palloc(10 + strlen(constraint->name) + 3 + 1);
606 strcpy(cstring, "nextval('\"");
607 strcat(cstring, constraint->name);
608 strcat(cstring, "\"')");
609 constraint->def = cstring;
610 constraint->keys = NULL;
612 column->constraints = lappend(column->constraints, constraint);
614 constraint = makeNode(Constraint);
615 constraint->contype = CONSTR_UNIQUE;
616 constraint->name = makeObjectName(stmt->relname,
619 column->constraints = lappend(column->constraints, constraint);
621 sequence = makeNode(CreateSeqStmt);
622 sequence->seqname = pstrdup(sname);
623 sequence->options = NIL;
625 elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
626 sequence->seqname, stmt->relname, column->colname);
628 blist = lcons(sequence, NIL);
631 /* Check for column constraints, if any... */
632 if (column->constraints != NIL)
634 clist = column->constraints;
637 constraint = lfirst(clist);
638 switch (constraint->contype)
643 * We should mark this explicitly, so we
644 * can tell if NULL and NOT NULL are both
647 if (column->is_not_null)
648 elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
649 " for '%s.%s'", stmt->relname, column->colname);
650 column->is_not_null = FALSE;
654 if (column->is_not_null)
655 elog(ERROR, "CREATE TABLE/NOT NULL already specified"
656 " for '%s.%s'", stmt->relname, column->colname);
657 column->is_not_null = TRUE;
661 if (column->defval != NULL)
662 elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
663 " for '%s.%s'", stmt->relname, column->colname);
664 column->defval = constraint->def;
668 if (constraint->name == NULL)
669 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
670 if (constraint->keys == NIL)
671 constraint->keys = lappend(constraint->keys, column);
672 dlist = lappend(dlist, constraint);
676 if (constraint->name == NULL)
677 constraint->name = makeObjectName(stmt->relname, column->colname, "key");
678 if (constraint->keys == NIL)
679 constraint->keys = lappend(constraint->keys, column);
680 dlist = lappend(dlist, constraint);
684 constraints = lappend(constraints, constraint);
685 if (constraint->name == NULL)
686 constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
690 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
693 clist = lnext(clist);
699 constraint = (Constraint *) element;
700 switch (constraint->contype)
703 if (constraint->name == NULL)
704 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
705 dlist = lappend(dlist, constraint);
709 dlist = lappend(dlist, constraint);
713 constraints = lappend(constraints, constraint);
718 elog(ERROR, "parser: illegal context for constraint (internal error)", NULL);
721 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
727 elog(ERROR, "parser: unrecognized node (internal error)", NULL);
730 elements = lnext(elements);
733 stmt->tableElts = columns;
734 stmt->constraints = constraints;
736 /* Now run through the "deferred list" to complete the query transformation.
737 * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
738 * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
740 * Note that this code does not currently look for all possible redundant cases
741 * and either ignore or stop with warning. The create might fail later when
742 * names for indices turn out to be duplicated, or a user might have specified
743 * extra useless indices which might hurt performance. - thomas 1997-12-08
747 constraint = lfirst(dlist);
748 Assert(nodeTag(constraint) == T_Constraint);
749 Assert((constraint->contype == CONSTR_PRIMARY)
750 || (constraint->contype == CONSTR_UNIQUE));
752 index = makeNode(IndexStmt);
754 index->unique = TRUE;
755 index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE : FALSE);
759 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
760 " for table '%s' are not allowed", stmt->relname);
761 pkey = (IndexStmt *) index;
764 if (constraint->name != NULL)
765 index->idxname = pstrdup(constraint->name);
766 else if (constraint->contype == CONSTR_PRIMARY)
767 index->idxname = makeObjectName(stmt->relname, NULL, "pkey");
769 index->idxname = NULL;
771 index->relname = stmt->relname;
772 index->accessMethod = "btree";
773 index->indexParams = NIL;
774 index->withClause = NIL;
775 index->whereClause = NULL;
777 keys = constraint->keys;
781 columns = stmt->tableElts;
783 while (columns != NIL)
785 column = lfirst(columns);
786 if (strcasecmp(column->colname, key->name) == 0)
790 columns = lnext(columns);
793 elog(ERROR, "CREATE TABLE column '%s' in key does not exist", key->name);
795 if (constraint->contype == CONSTR_PRIMARY)
796 column->is_not_null = TRUE;
797 iparam = makeNode(IndexElem);
798 iparam->name = pstrdup(column->colname);
800 iparam->class = NULL;
801 iparam->typename = NULL;
802 index->indexParams = lappend(index->indexParams, iparam);
804 if (index->idxname == NULL)
805 index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
810 if (index->idxname == NULL) /* should not happen */
811 elog(ERROR, "CREATE TABLE: failed to make implicit index name");
813 ilist = lappend(ilist, index);
814 dlist = lnext(dlist);
817 /* OK, now finally, if there is a primary key, then make sure that there aren't any redundant
818 * unique indices defined on columns. This can arise if someone specifies UNIQUE explicitly
819 * or if a SERIAL column was defined along with a table PRIMARY KEY constraint.
820 * - thomas 1999-05-11
832 index = lfirst(dlist);
833 pcols = pkey->indexParams;
834 icols = index->indexParams;
836 plen = length(pcols);
837 ilen = length(icols);
839 /* Not the same as the primary key? Then we should look... */
840 if ((index != pkey) && (ilen == plen))
843 while ((pcols != NIL) && (icols != NIL))
845 IndexElem *pcol = lfirst(pcols);
846 IndexElem *icol = lfirst(icols);
847 char *pname = pcol->name;
848 char *iname = icol->name;
850 /* different names? then no match... */
851 if (strcmp(iname, pname) != 0)
856 pcols = lnext(pcols);
857 icols = lnext(icols);
862 ilist = lappend(ilist, index);
863 dlist = lnext(dlist);
870 index = lfirst(dlist);
871 elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
872 (index->primary ? "PRIMARY KEY" : "UNIQUE"),
873 index->idxname, stmt->relname);
874 dlist = lnext(dlist);
877 q->utilityStmt = (Node *) stmt;
878 extras_before = blist;
879 extras_after = ilist;
882 } /* transformCreateStmt() */
885 * transformIndexStmt -
886 * transforms the qualification of the index statement
889 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
893 qry = makeNode(Query);
894 qry->commandType = CMD_UTILITY;
896 /* take care of the where clause */
897 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
898 qry->hasSubLinks = pstate->p_hasSubLinks;
900 stmt->rangetable = pstate->p_rtable;
902 qry->utilityStmt = (Node *) stmt;
908 * transformExtendStmt -
909 * transform the qualifications of the Extend Index Statement
913 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
917 qry = makeNode(Query);
918 qry->commandType = CMD_UTILITY;
920 /* take care of the where clause */
921 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
922 qry->hasSubLinks = pstate->p_hasSubLinks;
924 stmt->rangetable = pstate->p_rtable;
926 qry->utilityStmt = (Node *) stmt;
931 * transformRuleStmt -
932 * transform a Create Rule Statement. The actions is a list of parse
933 * trees which is transformed into a list of query trees.
936 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
942 qry = makeNode(Query);
943 qry->commandType = CMD_UTILITY;
946 * 'instead nothing' rules with a qualification need a query a
947 * rangetable so the rewrite handler can add the negated rule
948 * qualification to the original query. We create a query with the new
949 * command type CMD_NOTHING here that is treated special by the
952 if (stmt->actions == NIL)
954 Query *nothing_qry = makeNode(Query);
956 nothing_qry->commandType = CMD_NOTHING;
958 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
960 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
963 nothing_qry->rtable = pstate->p_rtable;
965 stmt->actions = lappend(NIL, nothing_qry);
968 actions = stmt->actions;
971 * transform each statment, like parse_analyze()
973 while (actions != NIL)
977 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
980 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
982 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
985 pstate->p_last_resno = 1;
986 pstate->p_is_rule = true; /* for expand all */
987 pstate->p_hasAggs = false;
989 action = (Query *) lfirst(actions);
990 if (action->commandType != CMD_NOTHING)
991 lfirst(actions) = transformStmt(pstate, lfirst(actions));
992 actions = lnext(actions);
995 /* take care of the where clause */
996 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
997 qry->hasSubLinks = pstate->p_hasSubLinks;
999 qry->utilityStmt = (Node *) stmt;
1005 * transformSelectStmt -
1006 * transforms a Select Statement
1010 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
1012 Query *qry = makeNode(Query);
1015 qry->commandType = CMD_SELECT;
1017 /* set up a range table */
1018 makeRangeTable(pstate, stmt->fromClause, &fromQual);
1020 qry->uniqueFlag = stmt->unique;
1022 qry->into = stmt->into;
1023 qry->isTemp = stmt->istemp;
1024 qry->isPortal = FALSE;
1026 qry->targetList = transformTargetList(pstate, stmt->targetList);
1028 qry->qual = transformWhereClause(pstate, stmt->whereClause, fromQual);
1030 /* Initial processing of HAVING clause is just like WHERE clause.
1031 * Additional work will be done in optimizer/plan/planner.c.
1033 qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
1035 qry->groupClause = transformGroupClause(pstate,
1039 qry->sortClause = transformSortClause(pstate,
1044 qry->hasSubLinks = pstate->p_hasSubLinks;
1045 qry->hasAggs = pstate->p_hasAggs;
1046 if (pstate->p_hasAggs || qry->groupClause)
1047 parseCheckAggregates(pstate, qry);
1050 * If there is a havingQual but there are no aggregates, then there is
1051 * something wrong with the query because HAVING must contain
1052 * aggregates in its expressions! Otherwise the query could have been
1053 * formulated using the WHERE clause.
1055 if (qry->havingQual && ! qry->hasAggs)
1056 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
1059 * The INSERT INTO ... SELECT ... could have a UNION in child, so
1060 * unionClause may be false
1062 qry->unionall = stmt->unionall;
1065 * Just hand through the unionClause and intersectClause. We will
1066 * handle it in the function Except_Intersect_Rewrite()
1068 qry->unionClause = stmt->unionClause;
1069 qry->intersectClause = stmt->intersectClause;
1071 qry->rtable = pstate->p_rtable;
1073 if (stmt->forUpdate != NULL)
1074 transformForUpdate(qry, stmt->forUpdate);
1076 return (Query *) qry;
1080 * transformUpdateStmt -
1081 * transforms an update statement
1085 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
1087 Query *qry = makeNode(Query);
1088 List *origTargetList;
1091 qry->commandType = CMD_UPDATE;
1092 pstate->p_is_update = true;
1095 * the FROM clause is non-standard SQL syntax. We used to be able to
1096 * do this with REPLACE in POSTQUEL so we keep the feature.
1098 makeRangeTable(pstate, stmt->fromClause, NULL);
1099 setTargetTable(pstate, stmt->relname);
1101 qry->targetList = transformTargetList(pstate, stmt->targetList);
1103 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
1105 qry->hasSubLinks = pstate->p_hasSubLinks;
1107 qry->rtable = pstate->p_rtable;
1108 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
1110 qry->hasAggs = pstate->p_hasAggs;
1111 if (pstate->p_hasAggs)
1112 parseCheckAggregates(pstate, qry);
1115 * Now we are done with SELECT-like processing, and can get on with
1116 * transforming the target list to match the UPDATE target columns.
1119 /* Prepare to assign non-conflicting resnos to resjunk attributes */
1120 if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
1121 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
1123 /* Prepare non-junk columns for assignment to target table */
1124 origTargetList = stmt->targetList;
1125 foreach(tl, qry->targetList)
1127 TargetEntry *tle = (TargetEntry *) lfirst(tl);
1128 Resdom *resnode = tle->resdom;
1129 ResTarget *origTarget;
1131 if (resnode->resjunk)
1133 /* Resjunk nodes need no additional processing, but be sure they
1134 * have names and resnos that do not match any target columns;
1135 * else rewriter or planner might get confused.
1137 resnode->resname = "?resjunk?";
1138 resnode->resno = (AttrNumber) pstate->p_last_resno++;
1141 if (origTargetList == NIL)
1142 elog(ERROR, "UPDATE target count mismatch --- internal error");
1143 origTarget = (ResTarget *) lfirst(origTargetList);
1144 updateTargetListEntry(pstate, tle,
1145 origTarget->name, origTarget->indirection);
1146 origTargetList = lnext(origTargetList);
1148 if (origTargetList != NIL)
1149 elog(ERROR, "UPDATE target count mismatch --- internal error");
1151 return (Query *) qry;
1155 * transformCursorStmt -
1156 * transform a Create Cursor Statement
1160 transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
1164 qry = transformSelectStmt(pstate, stmt);
1166 qry->into = stmt->portalname;
1167 qry->isTemp = stmt->istemp;
1168 qry->isPortal = TRUE;
1169 qry->isBinary = stmt->binary; /* internal portal */
1174 /* This function steps through the tree
1175 * built up by the select_w_o_sort rule
1176 * and builds a list of all SelectStmt Nodes found
1177 * The built up list is handed back in **select_list.
1178 * If one of the SelectStmt Nodes has the 'unionall' flag
1179 * set to true *unionall_present hands back 'true' */
1181 create_select_list(Node *ptr, List **select_list, bool *unionall_present)
1183 if (IsA(ptr, SelectStmt))
1185 *select_list = lappend(*select_list, ptr);
1186 if (((SelectStmt *) ptr)->unionall == TRUE)
1187 *unionall_present = TRUE;
1191 /* Recursively call for all arguments. A NOT expr has no lexpr! */
1192 if (((A_Expr *) ptr)->lexpr != NULL)
1193 create_select_list(((A_Expr *) ptr)->lexpr, select_list, unionall_present);
1194 create_select_list(((A_Expr *) ptr)->rexpr, select_list, unionall_present);
1197 /* Changes the A_Expr Nodes to Expr Nodes and exchanges ANDs and ORs.
1198 * The reason for the exchange is easy: We implement INTERSECTs and EXCEPTs
1199 * by rewriting these queries to semantically equivalent queries that use
1200 * IN and NOT IN subselects. To be able to use all three operations
1201 * (UNIONs INTERSECTs and EXCEPTs) in one complex query we have to
1202 * translate the queries into Disjunctive Normal Form (DNF). Unfortunately
1203 * there is no function 'dnfify' but there is a function 'cnfify'
1204 * which produces DNF when we exchange ANDs and ORs before calling
1205 * 'cnfify' and exchange them back in the result.
1207 * If an EXCEPT or INTERSECT is present *intersect_present
1208 * hands back 'true' */
1210 A_Expr_to_Expr(Node *ptr, bool *intersect_present)
1212 Node *result = NULL;
1214 switch (nodeTag(ptr))
1218 A_Expr *a = (A_Expr *) ptr;
1224 Expr *expr = makeNode(Expr);
1225 Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1226 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1228 *intersect_present = TRUE;
1230 expr->typeOid = BOOLOID;
1231 expr->opType = OR_EXPR;
1232 expr->args = makeList(lexpr, rexpr, -1);
1233 result = (Node *) expr;
1238 Expr *expr = makeNode(Expr);
1239 Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1240 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1242 expr->typeOid = BOOLOID;
1243 expr->opType = AND_EXPR;
1244 expr->args = makeList(lexpr, rexpr, -1);
1245 result = (Node *) expr;
1250 Expr *expr = makeNode(Expr);
1251 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1253 expr->typeOid = BOOLOID;
1254 expr->opType = NOT_EXPR;
1255 expr->args = makeList(rexpr, -1);
1256 result = (Node *) expr;
1269 CheckSelectForUpdate(Query *qry)
1271 if (qry->unionClause != NULL)
1272 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT clause");
1273 if (qry->uniqueFlag != NULL)
1274 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
1275 if (qry->groupClause != NULL)
1276 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
1278 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
1282 transformForUpdate(Query *qry, List *forUpdate)
1284 List *rowMark = NULL;
1289 CheckSelectForUpdate(qry);
1291 if (lfirst(forUpdate) == NULL) /* all tables */
1294 foreach(l, qry->rtable)
1296 newrm = makeNode(RowMark);
1298 newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1299 rowMark = lappend(rowMark, newrm);
1301 qry->rowMark = nconc(qry->rowMark, rowMark);
1305 foreach(l, forUpdate)
1311 foreach(l2, qry->rtable)
1313 if (strcmp(((RangeTblEntry *) lfirst(l2))->refname, lfirst(l)) == 0)
1315 foreach(l3, rowMark)
1317 if (((RowMark *) lfirst(l3))->rti == i) /* duplicate */
1322 newrm = makeNode(RowMark);
1324 newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1325 rowMark = lappend(rowMark, newrm);
1332 elog(ERROR, "FOR UPDATE: relation %s not found in FROM clause", lfirst(l));
1335 qry->rowMark = rowMark;