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.112 1999/07/15 15:19:29 momjian Exp $
10 *-------------------------------------------------------------------------
19 #include "access/heapam.h"
20 #include "nodes/makefuncs.h"
21 #include "nodes/memnodes.h"
22 #include "nodes/pg_list.h"
23 #include "parser/analyze.h"
24 #include "parser/parse_agg.h"
25 #include "parser/parse_clause.h"
26 #include "parser/parse_node.h"
27 #include "parser/parse_relation.h"
28 #include "parser/parse_target.h"
29 #include "parser/parse_expr.h"
30 #include "catalog/pg_type.h"
33 #include "utils/builtins.h"
35 static Query *transformStmt(ParseState *pstate, Node *stmt);
36 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
37 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
38 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
39 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
40 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
41 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
42 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
43 static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
44 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
46 static void transformForUpdate(Query *qry, List *forUpdate);
47 void CheckSelectForUpdate(Query *qry);
49 List *extras_before = NIL;
50 List *extras_after = NIL;
54 * analyze a list of parse trees and transform them if necessary.
56 * Returns a list of transformed parse trees. Optimizable statements are
57 * all transformed to Query while the rest stays the same.
61 parse_analyze(List *pl, ParseState *parentParseState)
69 pstate = make_parsestate(parentParseState);
70 parsetree = transformStmt(pstate, lfirst(pl));
71 if (pstate->p_target_relation != NULL)
72 heap_close(pstate->p_target_relation);
74 while (extras_before != NIL)
76 result = lappend(result,
77 transformStmt(pstate, lfirst(extras_before)));
78 if (pstate->p_target_relation != NULL)
79 heap_close(pstate->p_target_relation);
80 extras_before = lnext(extras_before);
83 result = lappend(result, parsetree);
85 while (extras_after != NIL)
87 result = lappend(result,
88 transformStmt(pstate, lfirst(extras_after)));
89 if (pstate->p_target_relation != NULL)
90 heap_close(pstate->p_target_relation);
91 extras_after = lnext(extras_after);
103 * transform a Parse tree. If it is an optimizable statement, turn it
107 transformStmt(ParseState *pstate, Node *parseTree)
109 Query *result = NULL;
111 switch (nodeTag(parseTree))
113 /*------------------------
114 * Non-optimizable statements
115 *------------------------
118 result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
122 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
126 result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
130 result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
135 ViewStmt *n = (ViewStmt *) parseTree;
137 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
138 result = makeNode(Query);
139 result->commandType = CMD_UTILITY;
140 result->utilityStmt = (Node *) n;
146 MemoryContext oldcontext;
149 * make sure that this Query is allocated in TopMemory
150 * context because vacuum spans transactions and we don't
151 * want to lose the vacuum Query due to end-of-transaction
154 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
155 result = makeNode(Query);
156 result->commandType = CMD_UTILITY;
157 result->utilityStmt = (Node *) parseTree;
158 MemoryContextSwitchTo(oldcontext);
164 ExplainStmt *n = (ExplainStmt *) parseTree;
166 result = makeNode(Query);
167 result->commandType = CMD_UTILITY;
168 n->query = transformStmt(pstate, (Node *) n->query);
169 result->utilityStmt = (Node *) parseTree;
173 /*------------------------
174 * Optimizable statements
175 *------------------------
178 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
182 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
186 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
190 if (!((SelectStmt *) parseTree)->portalname)
192 result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
193 result->limitOffset = ((SelectStmt *) parseTree)->limitOffset;
194 result->limitCount = ((SelectStmt *) parseTree)->limitCount;
197 result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
203 * other statments don't require any transformation-- just
204 * return the original parsetree, yea!
206 result = makeNode(Query);
207 result->commandType = CMD_UTILITY;
208 result->utilityStmt = (Node *) parseTree;
215 * transformDeleteStmt -
216 * transforms a Delete Statement
219 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
221 Query *qry = makeNode(Query);
223 qry->commandType = CMD_DELETE;
225 /* set up a range table */
226 makeRangeTable(pstate, stmt->relname, NULL, NULL);
228 qry->uniqueFlag = NULL;
230 /* fix where clause */
231 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
232 qry->hasSubLinks = pstate->p_hasSubLinks;
234 qry->rtable = pstate->p_rtable;
235 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
237 qry->hasAggs = pstate->p_hasAggs;
238 if (pstate->p_hasAggs)
239 parseCheckAggregates(pstate, qry);
241 return (Query *) qry;
245 * transformInsertStmt -
246 * transform an Insert Statement
249 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
251 Query *qry = makeNode(Query); /* make a new query tree */
254 qry->commandType = CMD_INSERT;
255 pstate->p_is_insert = true;
257 /* set up a range table */
258 makeRangeTable(pstate, stmt->relname, stmt->fromClause, NULL);
260 qry->uniqueFlag = stmt->unique;
262 /* fix the target list */
263 icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
265 qry->targetList = transformTargetList(pstate, stmt->targetList);
267 /* DEFAULT handling */
268 if (length(qry->targetList) < pstate->p_target_relation->rd_att->natts &&
269 pstate->p_target_relation->rd_att->constr &&
270 pstate->p_target_relation->rd_att->constr->num_defval > 0)
272 Form_pg_attribute *att = pstate->p_target_relation->rd_att->attrs;
273 AttrDefault *defval = pstate->p_target_relation->rd_att->constr->defval;
274 int ndef = pstate->p_target_relation->rd_att->constr->num_defval;
277 * if stmt->cols == NIL then makeTargetNames returns list of all
278 * attrs. May have to shorten icolumns list...
280 if (stmt->cols == NIL)
283 int i = length(qry->targetList);
285 foreach(extrl, icolumns)
289 * decrements first, so if we started with zero items it
290 * will now be negative
297 * this an index into the targetList, so make sure we had one
302 freeList(lnext(extrl));
315 foreach(tl, icolumns)
317 id = (Ident *) lfirst(tl);
318 if (namestrcmp(&(att[defval[ndef].adnum - 1]->attname), id->name) == 0)
321 if (tl != NIL) /* something given for this attr */
325 * Nothing given for this attr with DEFAULT expr, so add new
326 * TargetEntry to qry->targetList. Note, that we set resno to
327 * defval[ndef].adnum: it's what
328 * transformTargetList()->make_targetlist_expr() does for
329 * INSERT ... SELECT. But for INSERT ... VALUES
330 * pstate->p_last_resno is used. It doesn't matter for
331 * "normal" using (planner creates proper target list in
332 * preptlist.c), but may break RULEs in some way. It seems
333 * better to create proper target list here...
335 te = makeTargetEntry(makeResdom(defval[ndef].adnum,
336 att[defval[ndef].adnum - 1]->atttypid,
337 att[defval[ndef].adnum - 1]->atttypmod,
338 pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
340 (Node *) stringToNode(defval[ndef].adbin));
341 qry->targetList = lappend(qry->targetList, te);
345 /* fix where clause */
346 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
349 * The havingQual has a similar meaning as "qual" in the where
350 * statement. So we can easily use the code from the "where clause"
351 * with some additional traversals done in
352 * .../optimizer/plan/planner.c
354 qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
356 qry->hasSubLinks = pstate->p_hasSubLinks;
358 /* now the range table will not change */
359 qry->rtable = pstate->p_rtable;
360 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
362 qry->groupClause = transformGroupClause(pstate,
366 /* fix order clause */
367 qry->sortClause = transformSortClause(pstate,
373 qry->hasAggs = pstate->p_hasAggs;
374 if (pstate->p_hasAggs || qry->groupClause)
375 parseCheckAggregates(pstate, qry);
378 * The INSERT INTO ... SELECT ... could have a UNION in child, so
379 * unionClause may be false ,
381 qry->unionall = stmt->unionall;
384 * Just hand through the unionClause and intersectClause. We will
385 * handle it in the function Except_Intersect_Rewrite()
387 qry->unionClause = stmt->unionClause;
388 qry->intersectClause = stmt->intersectClause;
391 * If there is a havingQual but there are no aggregates, then there is
392 * something wrong with the query because having must contain
393 * aggregates in its expressions! Otherwise the query could have been
394 * formulated using the where clause.
396 if ((qry->hasAggs == false) && (qry->havingQual != NULL))
398 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
399 return (Query *) NIL;
402 if (stmt->forUpdate != NULL)
403 transformForUpdate(qry, stmt->forUpdate);
405 return (Query *) qry;
411 * Create a name for an implicitly created index, sequence, constraint, etc.
413 * The parameters are: the original table name, the original field name, and
414 * a "type" string (such as "seq" or "pkey"). The field name and/or type
415 * can be NULL if not relevant.
417 * The result is a palloc'd string.
419 * The basic result we want is "name1_name2_type", omitting "_name2" or
420 * "_type" when those parameters are NULL. However, we must generate
421 * a name with less than NAMEDATALEN characters! So, we truncate one or
422 * both names if necessary to make a short-enough string. The type part
423 * is never truncated (so it had better be reasonably short).
425 * To reduce the probability of collisions, we might someday add more
426 * smarts to this routine, like including some "hash" characters computed
427 * from the truncated characters. Currently it seems best to keep it simple,
428 * so that the generated names are easily predictable by a person.
431 makeObjectName(char *name1, char *name2, char *typename)
434 int overhead = 0; /* chars needed for type and underscores */
435 int availchars; /* chars available for name(s) */
436 int name1chars; /* chars allocated to name1 */
437 int name2chars; /* chars allocated to name2 */
440 name1chars = strlen(name1);
443 name2chars = strlen(name2);
444 overhead++; /* allow for separating underscore */
449 overhead += strlen(typename) + 1;
451 availchars = NAMEDATALEN-1 - overhead;
453 /* If we must truncate, preferentially truncate the longer name.
454 * This logic could be expressed without a loop, but it's simple and
457 while (name1chars + name2chars > availchars)
459 if (name1chars > name2chars)
465 /* Now construct the string using the chosen lengths */
466 name = palloc(name1chars + name2chars + overhead + 1);
467 strncpy(name, name1, name1chars);
472 strncpy(name+ndx, name2, name2chars);
478 strcpy(name+ndx, typename);
487 CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
492 char typename[NAMEDATALEN];
494 /* The type name for makeObjectName is label, or labelN if that's
495 * necessary to prevent collisions among multiple indexes for the same
496 * table. Note there is no check for collisions with already-existing
497 * indexes; this ought to be rethought someday.
499 strcpy(typename, label);
503 iname = makeObjectName(table_name, column_name, typename);
505 foreach(ilist, indices)
507 IndexStmt *index = lfirst(ilist);
508 if (strcasecmp(iname, index->idxname) == 0)
511 /* ran through entire list? then no name conflict found so done */
515 /* the last one conflicted, so try a new name component */
517 sprintf(typename, "%s%d", label, ++pass);
524 * transformCreateStmt -
525 * transforms the "create table" statement
526 * SQL92 allows constraints to be scattered all over, so thumb through
527 * the columns and collect all constraints into one place.
528 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
529 * then expand those into multiple IndexStmt blocks.
530 * - thomas 1997-12-02
533 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
543 Constraint *constraint;
546 List *blist = NIL; /* "before list" of things to do before
547 * creating the table */
548 List *ilist = NIL; /* "index list" of things to do after
549 * creating the table */
555 q->commandType = CMD_UTILITY;
557 elements = stmt->tableElts;
558 constraints = stmt->constraints;
562 while (elements != NIL)
564 element = lfirst(elements);
565 switch (nodeTag(element))
568 column = (ColumnDef *) element;
569 columns = lappend(columns, column);
571 if (column->is_sequence)
575 CreateSeqStmt *sequence;
577 sname = makeObjectName(stmt->relname, column->colname,
579 constraint = makeNode(Constraint);
580 constraint->contype = CONSTR_DEFAULT;
581 constraint->name = sname;
582 cstring = palloc(10 + strlen(constraint->name) + 3 + 1);
583 strcpy(cstring, "nextval('\"");
584 strcat(cstring, constraint->name);
585 strcat(cstring, "\"')");
586 constraint->def = cstring;
587 constraint->keys = NULL;
589 column->constraints = lappend(column->constraints, constraint);
591 constraint = makeNode(Constraint);
592 constraint->contype = CONSTR_UNIQUE;
593 constraint->name = makeObjectName(stmt->relname,
596 column->constraints = lappend(column->constraints, constraint);
598 sequence = makeNode(CreateSeqStmt);
599 sequence->seqname = pstrdup(sname);
600 sequence->options = NIL;
602 elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
603 sequence->seqname, stmt->relname, column->colname);
605 blist = lcons(sequence, NIL);
608 if (column->constraints != NIL)
610 clist = column->constraints;
613 constraint = lfirst(clist);
614 switch (constraint->contype)
619 * We should mark this explicitly, so we
620 * can tell if NULL and NOT NULL are both
623 if (column->is_not_null)
624 elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
625 " for '%s.%s'", stmt->relname, column->colname);
626 column->is_not_null = FALSE;
630 if (column->is_not_null)
631 elog(ERROR, "CREATE TABLE/NOT NULL already specified"
632 " for '%s.%s'", stmt->relname, column->colname);
633 column->is_not_null = TRUE;
637 if (column->defval != NULL)
638 elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
639 " for '%s.%s'", stmt->relname, column->colname);
640 column->defval = constraint->def;
644 if (constraint->name == NULL)
645 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
646 if (constraint->keys == NIL)
647 constraint->keys = lappend(constraint->keys, column);
648 dlist = lappend(dlist, constraint);
652 if (constraint->name == NULL)
653 constraint->name = makeObjectName(stmt->relname, column->colname, "key");
654 if (constraint->keys == NIL)
655 constraint->keys = lappend(constraint->keys, column);
656 dlist = lappend(dlist, constraint);
660 constraints = lappend(constraints, constraint);
661 if (constraint->name == NULL)
662 constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
666 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
669 clist = lnext(clist);
675 constraint = (Constraint *) element;
676 switch (constraint->contype)
679 if (constraint->name == NULL)
680 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
681 dlist = lappend(dlist, constraint);
685 dlist = lappend(dlist, constraint);
689 constraints = lappend(constraints, constraint);
694 elog(ERROR, "parser: illegal context for constraint (internal error)", NULL);
697 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
703 elog(ERROR, "parser: unrecognized node (internal error)", NULL);
706 elements = lnext(elements);
709 stmt->tableElts = columns;
710 stmt->constraints = constraints;
712 /* Now run through the "deferred list" to complete the query transformation.
713 * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
714 * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
716 * Note that this code does not currently look for all possible redundant cases
717 * and either ignore or stop with warning. The create might fail later when
718 * names for indices turn out to be duplicated, or a user might have specified
719 * extra useless indices which might hurt performance. - thomas 1997-12-08
723 constraint = lfirst(dlist);
724 Assert(nodeTag(constraint) == T_Constraint);
725 Assert((constraint->contype == CONSTR_PRIMARY)
726 || (constraint->contype == CONSTR_UNIQUE));
728 index = makeNode(IndexStmt);
730 index->unique = TRUE;
731 index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE : FALSE);
735 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
736 " for table '%s' are not allowed", stmt->relname);
737 pkey = (IndexStmt *) index;
740 if (constraint->name != NULL)
741 index->idxname = pstrdup(constraint->name);
742 else if (constraint->contype == CONSTR_PRIMARY)
743 index->idxname = makeObjectName(stmt->relname, NULL, "pkey");
745 index->idxname = NULL;
747 index->relname = stmt->relname;
748 index->accessMethod = "btree";
749 index->indexParams = NIL;
750 index->withClause = NIL;
751 index->whereClause = NULL;
753 keys = constraint->keys;
757 columns = stmt->tableElts;
759 while (columns != NIL)
761 column = lfirst(columns);
762 if (strcasecmp(column->colname, key->name) == 0)
766 columns = lnext(columns);
769 elog(ERROR, "CREATE TABLE column '%s' in key does not exist", key->name);
771 if (constraint->contype == CONSTR_PRIMARY)
772 column->is_not_null = TRUE;
773 iparam = makeNode(IndexElem);
774 iparam->name = pstrdup(column->colname);
776 iparam->class = NULL;
777 iparam->typename = NULL;
778 index->indexParams = lappend(index->indexParams, iparam);
780 if (index->idxname == NULL)
781 index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
786 if (index->idxname == NULL) /* should not happen */
787 elog(ERROR, "CREATE TABLE: failed to make implicit index name");
789 ilist = lappend(ilist, index);
790 dlist = lnext(dlist);
793 /* OK, now finally, if there is a primary key, then make sure that there aren't any redundant
794 * unique indices defined on columns. This can arise if someone specifies UNIQUE explicitly
795 * or if a SERIAL column was defined along with a table PRIMARY KEY constraint.
796 * - thomas 1999-05-11
798 if ((pkey != NULL) && (length(lfirst(pkey->indexParams)) == 1))
806 index = lfirst(dlist);
809 * has a single column argument, so might be a conflicting
813 && (length(index->indexParams) == 1))
815 char *pname = ((IndexElem *) lfirst(index->indexParams))->name;
816 char *iname = ((IndexElem *) lfirst(index->indexParams))->name;
818 /* same names? then don't keep... */
819 keep = (strcmp(iname, pname) != 0);
823 ilist = lappend(ilist, index);
824 dlist = lnext(dlist);
831 index = lfirst(dlist);
832 elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
833 (index->primary ? "PRIMARY KEY" : "UNIQUE"),
834 index->idxname, stmt->relname);
835 dlist = lnext(dlist);
838 q->utilityStmt = (Node *) stmt;
839 extras_before = blist;
840 extras_after = ilist;
843 } /* transformCreateStmt() */
846 * transformIndexStmt -
847 * transforms the qualification of the index statement
850 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
854 qry = makeNode(Query);
855 qry->commandType = CMD_UTILITY;
857 /* take care of the where clause */
858 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
859 qry->hasSubLinks = pstate->p_hasSubLinks;
861 stmt->rangetable = pstate->p_rtable;
863 qry->utilityStmt = (Node *) stmt;
869 * transformExtendStmt -
870 * transform the qualifications of the Extend Index Statement
874 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
878 qry = makeNode(Query);
879 qry->commandType = CMD_UTILITY;
881 /* take care of the where clause */
882 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
883 qry->hasSubLinks = pstate->p_hasSubLinks;
885 stmt->rangetable = pstate->p_rtable;
887 qry->utilityStmt = (Node *) stmt;
892 * transformRuleStmt -
893 * transform a Create Rule Statement. The actions is a list of parse
894 * trees which is transformed into a list of query trees.
897 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
903 qry = makeNode(Query);
904 qry->commandType = CMD_UTILITY;
907 * 'instead nothing' rules with a qualification need a query a
908 * rangetable so the rewrite handler can add the negated rule
909 * qualification to the original query. We create a query with the new
910 * command type CMD_NOTHING here that is treated special by the
913 if (stmt->actions == NIL)
915 Query *nothing_qry = makeNode(Query);
917 nothing_qry->commandType = CMD_NOTHING;
919 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
921 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
924 nothing_qry->rtable = pstate->p_rtable;
926 stmt->actions = lappend(NIL, nothing_qry);
929 actions = stmt->actions;
932 * transform each statment, like parse_analyze()
934 while (actions != NIL)
938 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
941 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
943 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
946 pstate->p_last_resno = 1;
947 pstate->p_is_rule = true; /* for expand all */
948 pstate->p_hasAggs = false;
950 action = (Query *) lfirst(actions);
951 if (action->commandType != CMD_NOTHING)
952 lfirst(actions) = transformStmt(pstate, lfirst(actions));
953 actions = lnext(actions);
956 /* take care of the where clause */
957 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
958 qry->hasSubLinks = pstate->p_hasSubLinks;
960 qry->utilityStmt = (Node *) stmt;
966 * transformSelectStmt -
967 * transforms a Select Statement
971 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
973 Query *qry = makeNode(Query);
976 qry->commandType = CMD_SELECT;
978 /* set up a range table */
979 makeRangeTable(pstate, NULL, stmt->fromClause, &qual);
981 qry->uniqueFlag = stmt->unique;
983 qry->into = stmt->into;
984 qry->isTemp = stmt->istemp;
985 qry->isPortal = FALSE;
987 qry->targetList = transformTargetList(pstate, stmt->targetList);
989 qry->qual = transformWhereClause(pstate, stmt->whereClause, qual);
992 * The havingQual has a similar meaning as "qual" in the where
993 * statement. So we can easily use the code from the "where clause"
994 * with some additional traversals done in optimizer/plan/planner.c
996 qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
998 qry->hasSubLinks = pstate->p_hasSubLinks;
1000 qry->sortClause = transformSortClause(pstate,
1006 qry->groupClause = transformGroupClause(pstate,
1009 qry->rtable = pstate->p_rtable;
1011 qry->hasAggs = pstate->p_hasAggs;
1012 if (pstate->p_hasAggs || qry->groupClause)
1013 parseCheckAggregates(pstate, qry);
1016 * The INSERT INTO ... SELECT ... could have a UNION in child, so
1017 * unionClause may be false
1019 qry->unionall = stmt->unionall;
1022 * Just hand through the unionClause and intersectClause. We will
1023 * handle it in the function Except_Intersect_Rewrite()
1025 qry->unionClause = stmt->unionClause;
1026 qry->intersectClause = stmt->intersectClause;
1029 * If there is a havingQual but there are no aggregates, then there is
1030 * something wrong with the query because having must contain
1031 * aggregates in its expressions! Otherwise the query could have been
1032 * formulated using the where clause.
1034 if ((qry->hasAggs == false) && (qry->havingQual != NULL))
1036 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
1037 return (Query *) NIL;
1040 if (stmt->forUpdate != NULL)
1041 transformForUpdate(qry, stmt->forUpdate);
1043 return (Query *) qry;
1047 * transformUpdateStmt -
1048 * transforms an update statement
1052 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
1054 Query *qry = makeNode(Query);
1056 qry->commandType = CMD_UPDATE;
1057 pstate->p_is_update = true;
1060 * the FROM clause is non-standard SQL syntax. We used to be able to
1061 * do this with REPLACE in POSTQUEL so we keep the feature.
1063 makeRangeTable(pstate, stmt->relname, stmt->fromClause, NULL);
1065 qry->targetList = transformTargetList(pstate, stmt->targetList);
1067 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
1068 qry->hasSubLinks = pstate->p_hasSubLinks;
1070 qry->rtable = pstate->p_rtable;
1072 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
1074 qry->hasAggs = pstate->p_hasAggs;
1075 if (pstate->p_hasAggs)
1076 parseCheckAggregates(pstate, qry);
1078 return (Query *) qry;
1082 * transformCursorStmt -
1083 * transform a Create Cursor Statement
1087 transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
1091 qry = transformSelectStmt(pstate, stmt);
1093 qry->into = stmt->portalname;
1094 qry->isTemp = stmt->istemp;
1095 qry->isPortal = TRUE;
1096 qry->isBinary = stmt->binary; /* internal portal */
1101 /* This function steps through the tree
1102 * built up by the select_w_o_sort rule
1103 * and builds a list of all SelectStmt Nodes found
1104 * The built up list is handed back in **select_list.
1105 * If one of the SelectStmt Nodes has the 'unionall' flag
1106 * set to true *unionall_present hands back 'true' */
1108 create_select_list(Node *ptr, List **select_list, bool *unionall_present)
1110 if (IsA(ptr, SelectStmt))
1112 *select_list = lappend(*select_list, ptr);
1113 if (((SelectStmt *) ptr)->unionall == TRUE)
1114 *unionall_present = TRUE;
1118 /* Recursively call for all arguments. A NOT expr has no lexpr! */
1119 if (((A_Expr *) ptr)->lexpr != NULL)
1120 create_select_list(((A_Expr *) ptr)->lexpr, select_list, unionall_present);
1121 create_select_list(((A_Expr *) ptr)->rexpr, select_list, unionall_present);
1124 /* Changes the A_Expr Nodes to Expr Nodes and exchanges ANDs and ORs.
1125 * The reason for the exchange is easy: We implement INTERSECTs and EXCEPTs
1126 * by rewriting these queries to semantically equivalent queries that use
1127 * IN and NOT IN subselects. To be able to use all three operations
1128 * (UNIONs INTERSECTs and EXCEPTs) in one complex query we have to
1129 * translate the queries into Disjunctive Normal Form (DNF). Unfortunately
1130 * there is no function 'dnfify' but there is a function 'cnfify'
1131 * which produces DNF when we exchange ANDs and ORs before calling
1132 * 'cnfify' and exchange them back in the result.
1134 * If an EXCEPT or INTERSECT is present *intersect_present
1135 * hands back 'true' */
1137 A_Expr_to_Expr(Node *ptr, bool *intersect_present)
1139 Node *result = NULL;
1141 switch (nodeTag(ptr))
1145 A_Expr *a = (A_Expr *) ptr;
1151 Expr *expr = makeNode(Expr);
1152 Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1153 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1155 *intersect_present = TRUE;
1157 expr->typeOid = BOOLOID;
1158 expr->opType = OR_EXPR;
1159 expr->args = makeList(lexpr, rexpr, -1);
1160 result = (Node *) expr;
1165 Expr *expr = makeNode(Expr);
1166 Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1167 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1169 expr->typeOid = BOOLOID;
1170 expr->opType = AND_EXPR;
1171 expr->args = makeList(lexpr, rexpr, -1);
1172 result = (Node *) expr;
1177 Expr *expr = makeNode(Expr);
1178 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1180 expr->typeOid = BOOLOID;
1181 expr->opType = NOT_EXPR;
1182 expr->args = makeList(rexpr, -1);
1183 result = (Node *) expr;
1196 CheckSelectForUpdate(Query *qry)
1198 if (qry->unionClause != NULL)
1199 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT clause");
1200 if (qry->uniqueFlag != NULL)
1201 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
1202 if (qry->groupClause != NULL)
1203 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
1205 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
1209 transformForUpdate(Query *qry, List *forUpdate)
1211 List *rowMark = NULL;
1216 CheckSelectForUpdate(qry);
1218 if (lfirst(forUpdate) == NULL) /* all tables */
1221 foreach(l, qry->rtable)
1223 newrm = makeNode(RowMark);
1225 newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1226 rowMark = lappend(rowMark, newrm);
1228 qry->rowMark = nconc(qry->rowMark, rowMark);
1232 foreach(l, forUpdate)
1238 foreach(l2, qry->rtable)
1240 if (strcmp(((RangeTblEntry *) lfirst(l2))->refname, lfirst(l)) == 0)
1242 foreach(l3, rowMark)
1244 if (((RowMark *) lfirst(l3))->rti == i) /* duplicate */
1249 newrm = makeNode(RowMark);
1251 newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1252 rowMark = lappend(rowMark, newrm);
1259 elog(ERROR, "FOR UPDATE: relation %s not found in FROM clause", lfirst(l));
1262 qry->rowMark = rowMark;