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.113 1999/07/15 22:39:33 momjian Exp $
10 *-------------------------------------------------------------------------
19 #include "access/heapam.h"
20 #include "nodes/makefuncs.h"
21 #include "parser/analyze.h"
22 #include "parser/parse_agg.h"
23 #include "parser/parse_clause.h"
24 #include "parser/parse_relation.h"
25 #include "parser/parse_target.h"
26 #include "catalog/pg_type.h"
29 #include "utils/builtins.h"
31 static Query *transformStmt(ParseState *pstate, Node *stmt);
32 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
33 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
34 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
35 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
36 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
37 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
38 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
39 static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
40 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
42 static void transformForUpdate(Query *qry, List *forUpdate);
43 void CheckSelectForUpdate(Query *qry);
45 List *extras_before = NIL;
46 List *extras_after = NIL;
50 * analyze a list of parse trees and transform them if necessary.
52 * Returns a list of transformed parse trees. Optimizable statements are
53 * all transformed to Query while the rest stays the same.
57 parse_analyze(List *pl, ParseState *parentParseState)
65 pstate = make_parsestate(parentParseState);
66 parsetree = transformStmt(pstate, lfirst(pl));
67 if (pstate->p_target_relation != NULL)
68 heap_close(pstate->p_target_relation);
70 while (extras_before != NIL)
72 result = lappend(result,
73 transformStmt(pstate, lfirst(extras_before)));
74 if (pstate->p_target_relation != NULL)
75 heap_close(pstate->p_target_relation);
76 extras_before = lnext(extras_before);
79 result = lappend(result, parsetree);
81 while (extras_after != NIL)
83 result = lappend(result,
84 transformStmt(pstate, lfirst(extras_after)));
85 if (pstate->p_target_relation != NULL)
86 heap_close(pstate->p_target_relation);
87 extras_after = lnext(extras_after);
99 * transform a Parse tree. If it is an optimizable statement, turn it
103 transformStmt(ParseState *pstate, Node *parseTree)
105 Query *result = NULL;
107 switch (nodeTag(parseTree))
109 /*------------------------
110 * Non-optimizable statements
111 *------------------------
114 result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
118 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
122 result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
126 result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
131 ViewStmt *n = (ViewStmt *) parseTree;
133 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
134 result = makeNode(Query);
135 result->commandType = CMD_UTILITY;
136 result->utilityStmt = (Node *) n;
142 MemoryContext oldcontext;
145 * make sure that this Query is allocated in TopMemory
146 * context because vacuum spans transactions and we don't
147 * want to lose the vacuum Query due to end-of-transaction
150 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
151 result = makeNode(Query);
152 result->commandType = CMD_UTILITY;
153 result->utilityStmt = (Node *) parseTree;
154 MemoryContextSwitchTo(oldcontext);
160 ExplainStmt *n = (ExplainStmt *) parseTree;
162 result = makeNode(Query);
163 result->commandType = CMD_UTILITY;
164 n->query = transformStmt(pstate, (Node *) n->query);
165 result->utilityStmt = (Node *) parseTree;
169 /*------------------------
170 * Optimizable statements
171 *------------------------
174 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
178 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
182 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
186 if (!((SelectStmt *) parseTree)->portalname)
188 result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
189 result->limitOffset = ((SelectStmt *) parseTree)->limitOffset;
190 result->limitCount = ((SelectStmt *) parseTree)->limitCount;
193 result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
199 * other statments don't require any transformation-- just
200 * return the original parsetree, yea!
202 result = makeNode(Query);
203 result->commandType = CMD_UTILITY;
204 result->utilityStmt = (Node *) parseTree;
211 * transformDeleteStmt -
212 * transforms a Delete Statement
215 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
217 Query *qry = makeNode(Query);
219 qry->commandType = CMD_DELETE;
221 /* set up a range table */
222 makeRangeTable(pstate, stmt->relname, NULL, NULL);
224 qry->uniqueFlag = NULL;
226 /* fix where clause */
227 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
228 qry->hasSubLinks = pstate->p_hasSubLinks;
230 qry->rtable = pstate->p_rtable;
231 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
233 qry->hasAggs = pstate->p_hasAggs;
234 if (pstate->p_hasAggs)
235 parseCheckAggregates(pstate, qry);
237 return (Query *) qry;
241 * transformInsertStmt -
242 * transform an Insert Statement
245 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
247 Query *qry = makeNode(Query); /* make a new query tree */
250 qry->commandType = CMD_INSERT;
251 pstate->p_is_insert = true;
253 /* set up a range table */
254 makeRangeTable(pstate, stmt->relname, stmt->fromClause, NULL);
256 qry->uniqueFlag = stmt->unique;
258 /* fix the target list */
259 icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
261 qry->targetList = transformTargetList(pstate, stmt->targetList);
263 /* DEFAULT handling */
264 if (length(qry->targetList) < pstate->p_target_relation->rd_att->natts &&
265 pstate->p_target_relation->rd_att->constr &&
266 pstate->p_target_relation->rd_att->constr->num_defval > 0)
268 Form_pg_attribute *att = pstate->p_target_relation->rd_att->attrs;
269 AttrDefault *defval = pstate->p_target_relation->rd_att->constr->defval;
270 int ndef = pstate->p_target_relation->rd_att->constr->num_defval;
273 * if stmt->cols == NIL then makeTargetNames returns list of all
274 * attrs. May have to shorten icolumns list...
276 if (stmt->cols == NIL)
279 int i = length(qry->targetList);
281 foreach(extrl, icolumns)
285 * decrements first, so if we started with zero items it
286 * will now be negative
293 * this an index into the targetList, so make sure we had one
298 freeList(lnext(extrl));
311 foreach(tl, icolumns)
313 id = (Ident *) lfirst(tl);
314 if (namestrcmp(&(att[defval[ndef].adnum - 1]->attname), id->name) == 0)
317 if (tl != NIL) /* something given for this attr */
321 * Nothing given for this attr with DEFAULT expr, so add new
322 * TargetEntry to qry->targetList. Note, that we set resno to
323 * defval[ndef].adnum: it's what
324 * transformTargetList()->make_targetlist_expr() does for
325 * INSERT ... SELECT. But for INSERT ... VALUES
326 * pstate->p_last_resno is used. It doesn't matter for
327 * "normal" using (planner creates proper target list in
328 * preptlist.c), but may break RULEs in some way. It seems
329 * better to create proper target list here...
331 te = makeTargetEntry(makeResdom(defval[ndef].adnum,
332 att[defval[ndef].adnum - 1]->atttypid,
333 att[defval[ndef].adnum - 1]->atttypmod,
334 pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
336 (Node *) stringToNode(defval[ndef].adbin));
337 qry->targetList = lappend(qry->targetList, te);
341 /* fix where clause */
342 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
345 * The havingQual has a similar meaning as "qual" in the where
346 * statement. So we can easily use the code from the "where clause"
347 * with some additional traversals done in
348 * .../optimizer/plan/planner.c
350 qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
352 qry->hasSubLinks = pstate->p_hasSubLinks;
354 /* now the range table will not change */
355 qry->rtable = pstate->p_rtable;
356 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
358 qry->groupClause = transformGroupClause(pstate,
362 /* fix order clause */
363 qry->sortClause = transformSortClause(pstate,
369 qry->hasAggs = pstate->p_hasAggs;
370 if (pstate->p_hasAggs || qry->groupClause)
371 parseCheckAggregates(pstate, qry);
374 * The INSERT INTO ... SELECT ... could have a UNION in child, so
375 * unionClause may be false ,
377 qry->unionall = stmt->unionall;
380 * Just hand through the unionClause and intersectClause. We will
381 * handle it in the function Except_Intersect_Rewrite()
383 qry->unionClause = stmt->unionClause;
384 qry->intersectClause = stmt->intersectClause;
387 * If there is a havingQual but there are no aggregates, then there is
388 * something wrong with the query because having must contain
389 * aggregates in its expressions! Otherwise the query could have been
390 * formulated using the where clause.
392 if ((qry->hasAggs == false) && (qry->havingQual != NULL))
394 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
395 return (Query *) NIL;
398 if (stmt->forUpdate != NULL)
399 transformForUpdate(qry, stmt->forUpdate);
401 return (Query *) qry;
407 * Create a name for an implicitly created index, sequence, constraint, etc.
409 * The parameters are: the original table name, the original field name, and
410 * a "type" string (such as "seq" or "pkey"). The field name and/or type
411 * can be NULL if not relevant.
413 * The result is a palloc'd string.
415 * The basic result we want is "name1_name2_type", omitting "_name2" or
416 * "_type" when those parameters are NULL. However, we must generate
417 * a name with less than NAMEDATALEN characters! So, we truncate one or
418 * both names if necessary to make a short-enough string. The type part
419 * is never truncated (so it had better be reasonably short).
421 * To reduce the probability of collisions, we might someday add more
422 * smarts to this routine, like including some "hash" characters computed
423 * from the truncated characters. Currently it seems best to keep it simple,
424 * so that the generated names are easily predictable by a person.
427 makeObjectName(char *name1, char *name2, char *typename)
430 int overhead = 0; /* chars needed for type and underscores */
431 int availchars; /* chars available for name(s) */
432 int name1chars; /* chars allocated to name1 */
433 int name2chars; /* chars allocated to name2 */
436 name1chars = strlen(name1);
439 name2chars = strlen(name2);
440 overhead++; /* allow for separating underscore */
445 overhead += strlen(typename) + 1;
447 availchars = NAMEDATALEN-1 - overhead;
449 /* If we must truncate, preferentially truncate the longer name.
450 * This logic could be expressed without a loop, but it's simple and
453 while (name1chars + name2chars > availchars)
455 if (name1chars > name2chars)
461 /* Now construct the string using the chosen lengths */
462 name = palloc(name1chars + name2chars + overhead + 1);
463 strncpy(name, name1, name1chars);
468 strncpy(name+ndx, name2, name2chars);
474 strcpy(name+ndx, typename);
483 CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
488 char typename[NAMEDATALEN];
490 /* The type name for makeObjectName is label, or labelN if that's
491 * necessary to prevent collisions among multiple indexes for the same
492 * table. Note there is no check for collisions with already-existing
493 * indexes; this ought to be rethought someday.
495 strcpy(typename, label);
499 iname = makeObjectName(table_name, column_name, typename);
501 foreach(ilist, indices)
503 IndexStmt *index = lfirst(ilist);
504 if (strcasecmp(iname, index->idxname) == 0)
507 /* ran through entire list? then no name conflict found so done */
511 /* the last one conflicted, so try a new name component */
513 sprintf(typename, "%s%d", label, ++pass);
520 * transformCreateStmt -
521 * transforms the "create table" statement
522 * SQL92 allows constraints to be scattered all over, so thumb through
523 * the columns and collect all constraints into one place.
524 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
525 * then expand those into multiple IndexStmt blocks.
526 * - thomas 1997-12-02
529 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
539 Constraint *constraint;
542 List *blist = NIL; /* "before list" of things to do before
543 * creating the table */
544 List *ilist = NIL; /* "index list" of things to do after
545 * creating the table */
551 q->commandType = CMD_UTILITY;
553 elements = stmt->tableElts;
554 constraints = stmt->constraints;
558 while (elements != NIL)
560 element = lfirst(elements);
561 switch (nodeTag(element))
564 column = (ColumnDef *) element;
565 columns = lappend(columns, column);
567 if (column->is_sequence)
571 CreateSeqStmt *sequence;
573 sname = makeObjectName(stmt->relname, column->colname,
575 constraint = makeNode(Constraint);
576 constraint->contype = CONSTR_DEFAULT;
577 constraint->name = sname;
578 cstring = palloc(10 + strlen(constraint->name) + 3 + 1);
579 strcpy(cstring, "nextval('\"");
580 strcat(cstring, constraint->name);
581 strcat(cstring, "\"')");
582 constraint->def = cstring;
583 constraint->keys = NULL;
585 column->constraints = lappend(column->constraints, constraint);
587 constraint = makeNode(Constraint);
588 constraint->contype = CONSTR_UNIQUE;
589 constraint->name = makeObjectName(stmt->relname,
592 column->constraints = lappend(column->constraints, constraint);
594 sequence = makeNode(CreateSeqStmt);
595 sequence->seqname = pstrdup(sname);
596 sequence->options = NIL;
598 elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
599 sequence->seqname, stmt->relname, column->colname);
601 blist = lcons(sequence, NIL);
604 if (column->constraints != NIL)
606 clist = column->constraints;
609 constraint = lfirst(clist);
610 switch (constraint->contype)
615 * We should mark this explicitly, so we
616 * can tell if NULL and NOT NULL are both
619 if (column->is_not_null)
620 elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
621 " for '%s.%s'", stmt->relname, column->colname);
622 column->is_not_null = FALSE;
626 if (column->is_not_null)
627 elog(ERROR, "CREATE TABLE/NOT NULL already specified"
628 " for '%s.%s'", stmt->relname, column->colname);
629 column->is_not_null = TRUE;
633 if (column->defval != NULL)
634 elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
635 " for '%s.%s'", stmt->relname, column->colname);
636 column->defval = constraint->def;
640 if (constraint->name == NULL)
641 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
642 if (constraint->keys == NIL)
643 constraint->keys = lappend(constraint->keys, column);
644 dlist = lappend(dlist, constraint);
648 if (constraint->name == NULL)
649 constraint->name = makeObjectName(stmt->relname, column->colname, "key");
650 if (constraint->keys == NIL)
651 constraint->keys = lappend(constraint->keys, column);
652 dlist = lappend(dlist, constraint);
656 constraints = lappend(constraints, constraint);
657 if (constraint->name == NULL)
658 constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
662 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
665 clist = lnext(clist);
671 constraint = (Constraint *) element;
672 switch (constraint->contype)
675 if (constraint->name == NULL)
676 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
677 dlist = lappend(dlist, constraint);
681 dlist = lappend(dlist, constraint);
685 constraints = lappend(constraints, constraint);
690 elog(ERROR, "parser: illegal context for constraint (internal error)", NULL);
693 elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
699 elog(ERROR, "parser: unrecognized node (internal error)", NULL);
702 elements = lnext(elements);
705 stmt->tableElts = columns;
706 stmt->constraints = constraints;
708 /* Now run through the "deferred list" to complete the query transformation.
709 * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
710 * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
712 * Note that this code does not currently look for all possible redundant cases
713 * and either ignore or stop with warning. The create might fail later when
714 * names for indices turn out to be duplicated, or a user might have specified
715 * extra useless indices which might hurt performance. - thomas 1997-12-08
719 constraint = lfirst(dlist);
720 Assert(nodeTag(constraint) == T_Constraint);
721 Assert((constraint->contype == CONSTR_PRIMARY)
722 || (constraint->contype == CONSTR_UNIQUE));
724 index = makeNode(IndexStmt);
726 index->unique = TRUE;
727 index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE : FALSE);
731 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
732 " for table '%s' are not allowed", stmt->relname);
733 pkey = (IndexStmt *) index;
736 if (constraint->name != NULL)
737 index->idxname = pstrdup(constraint->name);
738 else if (constraint->contype == CONSTR_PRIMARY)
739 index->idxname = makeObjectName(stmt->relname, NULL, "pkey");
741 index->idxname = NULL;
743 index->relname = stmt->relname;
744 index->accessMethod = "btree";
745 index->indexParams = NIL;
746 index->withClause = NIL;
747 index->whereClause = NULL;
749 keys = constraint->keys;
753 columns = stmt->tableElts;
755 while (columns != NIL)
757 column = lfirst(columns);
758 if (strcasecmp(column->colname, key->name) == 0)
762 columns = lnext(columns);
765 elog(ERROR, "CREATE TABLE column '%s' in key does not exist", key->name);
767 if (constraint->contype == CONSTR_PRIMARY)
768 column->is_not_null = TRUE;
769 iparam = makeNode(IndexElem);
770 iparam->name = pstrdup(column->colname);
772 iparam->class = NULL;
773 iparam->typename = NULL;
774 index->indexParams = lappend(index->indexParams, iparam);
776 if (index->idxname == NULL)
777 index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
782 if (index->idxname == NULL) /* should not happen */
783 elog(ERROR, "CREATE TABLE: failed to make implicit index name");
785 ilist = lappend(ilist, index);
786 dlist = lnext(dlist);
789 /* OK, now finally, if there is a primary key, then make sure that there aren't any redundant
790 * unique indices defined on columns. This can arise if someone specifies UNIQUE explicitly
791 * or if a SERIAL column was defined along with a table PRIMARY KEY constraint.
792 * - thomas 1999-05-11
794 if ((pkey != NULL) && (length(lfirst(pkey->indexParams)) == 1))
802 index = lfirst(dlist);
805 * has a single column argument, so might be a conflicting
809 && (length(index->indexParams) == 1))
811 char *pname = ((IndexElem *) lfirst(index->indexParams))->name;
812 char *iname = ((IndexElem *) lfirst(index->indexParams))->name;
814 /* same names? then don't keep... */
815 keep = (strcmp(iname, pname) != 0);
819 ilist = lappend(ilist, index);
820 dlist = lnext(dlist);
827 index = lfirst(dlist);
828 elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
829 (index->primary ? "PRIMARY KEY" : "UNIQUE"),
830 index->idxname, stmt->relname);
831 dlist = lnext(dlist);
834 q->utilityStmt = (Node *) stmt;
835 extras_before = blist;
836 extras_after = ilist;
839 } /* transformCreateStmt() */
842 * transformIndexStmt -
843 * transforms the qualification of the index statement
846 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
850 qry = makeNode(Query);
851 qry->commandType = CMD_UTILITY;
853 /* take care of the where clause */
854 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
855 qry->hasSubLinks = pstate->p_hasSubLinks;
857 stmt->rangetable = pstate->p_rtable;
859 qry->utilityStmt = (Node *) stmt;
865 * transformExtendStmt -
866 * transform the qualifications of the Extend Index Statement
870 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
874 qry = makeNode(Query);
875 qry->commandType = CMD_UTILITY;
877 /* take care of the where clause */
878 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
879 qry->hasSubLinks = pstate->p_hasSubLinks;
881 stmt->rangetable = pstate->p_rtable;
883 qry->utilityStmt = (Node *) stmt;
888 * transformRuleStmt -
889 * transform a Create Rule Statement. The actions is a list of parse
890 * trees which is transformed into a list of query trees.
893 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
899 qry = makeNode(Query);
900 qry->commandType = CMD_UTILITY;
903 * 'instead nothing' rules with a qualification need a query a
904 * rangetable so the rewrite handler can add the negated rule
905 * qualification to the original query. We create a query with the new
906 * command type CMD_NOTHING here that is treated special by the
909 if (stmt->actions == NIL)
911 Query *nothing_qry = makeNode(Query);
913 nothing_qry->commandType = CMD_NOTHING;
915 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
917 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
920 nothing_qry->rtable = pstate->p_rtable;
922 stmt->actions = lappend(NIL, nothing_qry);
925 actions = stmt->actions;
928 * transform each statment, like parse_analyze()
930 while (actions != NIL)
934 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
937 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
939 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
942 pstate->p_last_resno = 1;
943 pstate->p_is_rule = true; /* for expand all */
944 pstate->p_hasAggs = false;
946 action = (Query *) lfirst(actions);
947 if (action->commandType != CMD_NOTHING)
948 lfirst(actions) = transformStmt(pstate, lfirst(actions));
949 actions = lnext(actions);
952 /* take care of the where clause */
953 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause, NULL);
954 qry->hasSubLinks = pstate->p_hasSubLinks;
956 qry->utilityStmt = (Node *) stmt;
962 * transformSelectStmt -
963 * transforms a Select Statement
967 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
969 Query *qry = makeNode(Query);
972 qry->commandType = CMD_SELECT;
974 /* set up a range table */
975 makeRangeTable(pstate, NULL, stmt->fromClause, &qual);
977 qry->uniqueFlag = stmt->unique;
979 qry->into = stmt->into;
980 qry->isTemp = stmt->istemp;
981 qry->isPortal = FALSE;
983 qry->targetList = transformTargetList(pstate, stmt->targetList);
985 qry->qual = transformWhereClause(pstate, stmt->whereClause, qual);
988 * The havingQual has a similar meaning as "qual" in the where
989 * statement. So we can easily use the code from the "where clause"
990 * with some additional traversals done in optimizer/plan/planner.c
992 qry->havingQual = transformWhereClause(pstate, stmt->havingClause, NULL);
994 qry->hasSubLinks = pstate->p_hasSubLinks;
996 qry->sortClause = transformSortClause(pstate,
1002 qry->groupClause = transformGroupClause(pstate,
1005 qry->rtable = pstate->p_rtable;
1007 qry->hasAggs = pstate->p_hasAggs;
1008 if (pstate->p_hasAggs || qry->groupClause)
1009 parseCheckAggregates(pstate, qry);
1012 * The INSERT INTO ... SELECT ... could have a UNION in child, so
1013 * unionClause may be false
1015 qry->unionall = stmt->unionall;
1018 * Just hand through the unionClause and intersectClause. We will
1019 * handle it in the function Except_Intersect_Rewrite()
1021 qry->unionClause = stmt->unionClause;
1022 qry->intersectClause = stmt->intersectClause;
1025 * If there is a havingQual but there are no aggregates, then there is
1026 * something wrong with the query because having must contain
1027 * aggregates in its expressions! Otherwise the query could have been
1028 * formulated using the where clause.
1030 if ((qry->hasAggs == false) && (qry->havingQual != NULL))
1032 elog(ERROR, "SELECT/HAVING requires aggregates to be valid");
1033 return (Query *) NIL;
1036 if (stmt->forUpdate != NULL)
1037 transformForUpdate(qry, stmt->forUpdate);
1039 return (Query *) qry;
1043 * transformUpdateStmt -
1044 * transforms an update statement
1048 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
1050 Query *qry = makeNode(Query);
1052 qry->commandType = CMD_UPDATE;
1053 pstate->p_is_update = true;
1056 * the FROM clause is non-standard SQL syntax. We used to be able to
1057 * do this with REPLACE in POSTQUEL so we keep the feature.
1059 makeRangeTable(pstate, stmt->relname, stmt->fromClause, NULL);
1061 qry->targetList = transformTargetList(pstate, stmt->targetList);
1063 qry->qual = transformWhereClause(pstate, stmt->whereClause, NULL);
1064 qry->hasSubLinks = pstate->p_hasSubLinks;
1066 qry->rtable = pstate->p_rtable;
1068 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
1070 qry->hasAggs = pstate->p_hasAggs;
1071 if (pstate->p_hasAggs)
1072 parseCheckAggregates(pstate, qry);
1074 return (Query *) qry;
1078 * transformCursorStmt -
1079 * transform a Create Cursor Statement
1083 transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
1087 qry = transformSelectStmt(pstate, stmt);
1089 qry->into = stmt->portalname;
1090 qry->isTemp = stmt->istemp;
1091 qry->isPortal = TRUE;
1092 qry->isBinary = stmt->binary; /* internal portal */
1097 /* This function steps through the tree
1098 * built up by the select_w_o_sort rule
1099 * and builds a list of all SelectStmt Nodes found
1100 * The built up list is handed back in **select_list.
1101 * If one of the SelectStmt Nodes has the 'unionall' flag
1102 * set to true *unionall_present hands back 'true' */
1104 create_select_list(Node *ptr, List **select_list, bool *unionall_present)
1106 if (IsA(ptr, SelectStmt))
1108 *select_list = lappend(*select_list, ptr);
1109 if (((SelectStmt *) ptr)->unionall == TRUE)
1110 *unionall_present = TRUE;
1114 /* Recursively call for all arguments. A NOT expr has no lexpr! */
1115 if (((A_Expr *) ptr)->lexpr != NULL)
1116 create_select_list(((A_Expr *) ptr)->lexpr, select_list, unionall_present);
1117 create_select_list(((A_Expr *) ptr)->rexpr, select_list, unionall_present);
1120 /* Changes the A_Expr Nodes to Expr Nodes and exchanges ANDs and ORs.
1121 * The reason for the exchange is easy: We implement INTERSECTs and EXCEPTs
1122 * by rewriting these queries to semantically equivalent queries that use
1123 * IN and NOT IN subselects. To be able to use all three operations
1124 * (UNIONs INTERSECTs and EXCEPTs) in one complex query we have to
1125 * translate the queries into Disjunctive Normal Form (DNF). Unfortunately
1126 * there is no function 'dnfify' but there is a function 'cnfify'
1127 * which produces DNF when we exchange ANDs and ORs before calling
1128 * 'cnfify' and exchange them back in the result.
1130 * If an EXCEPT or INTERSECT is present *intersect_present
1131 * hands back 'true' */
1133 A_Expr_to_Expr(Node *ptr, bool *intersect_present)
1135 Node *result = NULL;
1137 switch (nodeTag(ptr))
1141 A_Expr *a = (A_Expr *) ptr;
1147 Expr *expr = makeNode(Expr);
1148 Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1149 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1151 *intersect_present = TRUE;
1153 expr->typeOid = BOOLOID;
1154 expr->opType = OR_EXPR;
1155 expr->args = makeList(lexpr, rexpr, -1);
1156 result = (Node *) expr;
1161 Expr *expr = makeNode(Expr);
1162 Node *lexpr = A_Expr_to_Expr(((A_Expr *) ptr)->lexpr, intersect_present);
1163 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1165 expr->typeOid = BOOLOID;
1166 expr->opType = AND_EXPR;
1167 expr->args = makeList(lexpr, rexpr, -1);
1168 result = (Node *) expr;
1173 Expr *expr = makeNode(Expr);
1174 Node *rexpr = A_Expr_to_Expr(((A_Expr *) ptr)->rexpr, intersect_present);
1176 expr->typeOid = BOOLOID;
1177 expr->opType = NOT_EXPR;
1178 expr->args = makeList(rexpr, -1);
1179 result = (Node *) expr;
1192 CheckSelectForUpdate(Query *qry)
1194 if (qry->unionClause != NULL)
1195 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT clause");
1196 if (qry->uniqueFlag != NULL)
1197 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
1198 if (qry->groupClause != NULL)
1199 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
1201 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
1205 transformForUpdate(Query *qry, List *forUpdate)
1207 List *rowMark = NULL;
1212 CheckSelectForUpdate(qry);
1214 if (lfirst(forUpdate) == NULL) /* all tables */
1217 foreach(l, qry->rtable)
1219 newrm = makeNode(RowMark);
1221 newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1222 rowMark = lappend(rowMark, newrm);
1224 qry->rowMark = nconc(qry->rowMark, rowMark);
1228 foreach(l, forUpdate)
1234 foreach(l2, qry->rtable)
1236 if (strcmp(((RangeTblEntry *) lfirst(l2))->refname, lfirst(l)) == 0)
1238 foreach(l3, rowMark)
1240 if (((RowMark *) lfirst(l3))->rti == i) /* duplicate */
1245 newrm = makeNode(RowMark);
1247 newrm->info = ROW_MARK_FOR_UPDATE | ROW_ACL_FOR_UPDATE;
1248 rowMark = lappend(rowMark, newrm);
1255 elog(ERROR, "FOR UPDATE: relation %s not found in FROM clause", lfirst(l));
1258 qry->rowMark = rowMark;