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.85 1998/09/01 04:30:15 momjian Exp $
12 *-------------------------------------------------------------------------
21 #include "access/heapam.h"
22 #include "nodes/makefuncs.h"
23 #include "nodes/memnodes.h"
24 #include "nodes/pg_list.h"
25 #include "parser/analyze.h"
26 #include "parser/parse_agg.h"
27 #include "parser/parse_clause.h"
28 #include "parser/parse_node.h"
29 #include "parser/parse_relation.h"
30 #include "parser/parse_target.h"
31 #include "utils/builtins.h"
32 #include "utils/mcxt.h"
34 #include "nodes/print.h"
37 static Query *transformStmt(ParseState *pstate, Node *stmt);
38 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
39 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
40 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
41 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
42 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
43 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
44 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
45 static Query *transformCursorStmt(ParseState *pstate, SelectStmt *stmt);
46 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
52 * analyze a list of parse trees and transform them if necessary.
54 * Returns a list of transformed parse trees. Optimizable statements are
55 * all transformed to Query while the rest stays the same.
59 parse_analyze(List *pl, ParseState *parentParseState)
61 QueryTreeList *result;
65 result = malloc(sizeof(QueryTreeList));
66 result->len = length(pl);
67 result->qtrees = (Query **) malloc(result->len * sizeof(Query *));
72 elog(DEBUG, "parse tree from yacc:\n---\n%s\n---\n", nodeToString(lfirst(pl)));
75 pstate = make_parsestate(parentParseState);
76 result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
77 if (pstate->p_target_relation != NULL)
78 heap_close(pstate->p_target_relation);
82 result->len += length(extras);
83 result->qtrees = (Query **) realloc(result->qtrees, result->len * sizeof(Query *));
86 result->qtrees[i++] = transformStmt(pstate, lfirst(extras));
87 if (pstate->p_target_relation != NULL)
88 heap_close(pstate->p_target_relation);
89 extras = lnext(extras);
102 * transform a Parse tree. If it is an optimizable statement, turn it
106 transformStmt(ParseState *pstate, Node *parseTree)
108 Query *result = NULL;
110 switch (nodeTag(parseTree))
112 /*------------------------
113 * Non-optimizable statements
114 *------------------------
117 result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
121 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
125 result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
129 result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
134 ViewStmt *n = (ViewStmt *) parseTree;
136 n->query = (Query *) transformStmt(pstate, (Node *) n->query);
137 result = makeNode(Query);
138 result->commandType = CMD_UTILITY;
139 result->utilityStmt = (Node *) n;
145 MemoryContext oldcontext;
148 * make sure that this Query is allocated in TopMemory
149 * context because vacuum spans transactions and we don't
150 * want to lose the vacuum Query due to end-of-transaction
153 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
154 result = makeNode(Query);
155 result->commandType = CMD_UTILITY;
156 result->utilityStmt = (Node *) parseTree;
157 MemoryContextSwitchTo(oldcontext);
163 ExplainStmt *n = (ExplainStmt *) parseTree;
165 result = makeNode(Query);
166 result->commandType = CMD_UTILITY;
167 n->query = transformStmt(pstate, (Node *) n->query);
168 result->utilityStmt = (Node *) parseTree;
172 /*------------------------
173 * Optimizable statements
174 *------------------------
177 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
181 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
185 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
189 if (!((SelectStmt *) parseTree)->portalname)
190 result = transformSelectStmt(pstate, (SelectStmt *) parseTree);
192 result = transformCursorStmt(pstate, (SelectStmt *) parseTree);
198 * other statments don't require any transformation-- just
199 * return the original parsetree, yea!
201 result = makeNode(Query);
202 result->commandType = CMD_UTILITY;
203 result->utilityStmt = (Node *) parseTree;
210 * transformDeleteStmt -
211 * transforms a Delete Statement
214 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
216 Query *qry = makeNode(Query);
218 qry->commandType = CMD_DELETE;
220 /* set up a range table */
221 makeRangeTable(pstate, stmt->relname, NULL);
223 qry->uniqueFlag = NULL;
225 /* fix where clause */
226 qry->qual = transformWhereClause(pstate, stmt->whereClause);
227 qry->hasSubLinks = pstate->p_hasSubLinks;
229 qry->rtable = pstate->p_rtable;
230 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
232 qry->hasAggs = pstate->p_hasAggs;
233 if (pstate->p_hasAggs)
234 parseCheckAggregates(pstate, qry);
236 return (Query *) qry;
240 * transformInsertStmt -
241 * transform an Insert Statement
244 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
246 Query *qry = makeNode(Query); /* make a new query tree */
249 qry->commandType = CMD_INSERT;
250 pstate->p_is_insert = true;
252 /* set up a range table */
253 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
255 qry->uniqueFlag = stmt->unique;
257 /* fix the target list */
258 icolumns = pstate->p_insert_columns = makeTargetNames(pstate, stmt->cols);
260 qry->targetList = transformTargetList(pstate, stmt->targetList);
262 /* DEFAULT handling */
263 if (length(qry->targetList) < pstate->p_target_relation->rd_att->natts &&
264 pstate->p_target_relation->rd_att->constr &&
265 pstate->p_target_relation->rd_att->constr->num_defval > 0)
267 Form_pg_attribute *att = pstate->p_target_relation->rd_att->attrs;
268 AttrDefault *defval = pstate->p_target_relation->rd_att->constr->defval;
269 int ndef = pstate->p_target_relation->rd_att->constr->num_defval;
272 * if stmt->cols == NIL then makeTargetNames returns list of all
273 * attrs: have to shorter icolumns list...
275 if (stmt->cols == NIL)
278 int i = length(qry->targetList);
280 foreach(extrl, icolumns)
285 freeList(lnext(extrl));
295 foreach(tl, icolumns)
297 id = (Ident *) lfirst(tl);
298 if (!namestrcmp(&(att[defval[ndef].adnum - 1]->attname), id->name))
301 if (tl != NIL) /* something given for this attr */
305 * Nothing given for this attr with DEFAULT expr, so add new
306 * TargetEntry to qry->targetList. Note, that we set resno to
307 * defval[ndef].adnum: it's what
308 * transformTargetList()->make_targetlist_expr() does for
309 * INSERT ... SELECT. But for INSERT ... VALUES
310 * pstate->p_last_resno is used. It doesn't matter for
311 * "normal" using (planner creates proper target list in
312 * preptlist.c), but may break RULEs in some way. It seems
313 * better to create proper target list here...
315 te = makeTargetEntry(makeResdom(defval[ndef].adnum,
316 att[defval[ndef].adnum - 1]->atttypid,
317 att[defval[ndef].adnum - 1]->atttypmod,
318 pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
320 (Node *) stringToNode(defval[ndef].adbin));
321 qry->targetList = lappend(qry->targetList, te);
325 /* fix where clause */
326 qry->qual = transformWhereClause(pstate, stmt->whereClause);
329 * The havingQual has a similar meaning as "qual" in the where
330 * statement. So we can easily use the code from the "where clause"
331 * with some additional traversals done in
332 * .../optimizer/plan/planner.c
334 qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
336 qry->hasSubLinks = pstate->p_hasSubLinks;
338 /* now the range table will not change */
339 qry->rtable = pstate->p_rtable;
340 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
342 qry->groupClause = transformGroupClause(pstate,
346 /* fix order clause */
347 qry->sortClause = transformSortClause(pstate,
353 qry->hasAggs = pstate->p_hasAggs;
354 if (pstate->p_hasAggs)
355 parseCheckAggregates(pstate, qry);
358 * The INSERT INTO ... SELECT ... could have a UNION in child, so
359 * unionClause may be false
361 qry->unionall = stmt->unionall;
362 qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
365 * If there is a havingQual but there are no aggregates, then there is
366 * something wrong with the query because having must contain
367 * aggregates in its expressions! Otherwise the query could have been
368 * formulated using the where clause.
370 if ((qry->hasAggs == false) && (qry->havingQual != NULL))
372 elog(ERROR, "This is not a valid having query!");
373 return (Query *) NIL;
376 return (Query *) qry;
381 * Create a table name from a list of fields.
384 makeTableName(void *elem,...)
389 char buf[NAMEDATALEN + 1];
393 va_start(args, elem);
398 /* not enough room for next part? then return nothing */
399 if ((strlen(buf) + strlen(name)) >= (sizeof(buf) - 1))
406 name = va_arg(args, void *);
411 name = palloc(strlen(buf) + 1);
418 CreateIndexName(char *table_name, char *column_name, char *label, List *indices)
424 char name2[NAMEDATALEN + 1];
426 /* use working storage, since we might be trying several possibilities */
427 strcpy(name2, column_name);
428 while (iname == NULL)
430 iname = makeTableName(table_name, name2, label, NULL);
431 /* unable to make a name at all? then quit */
438 index = lfirst(ilist);
439 if (strcasecmp(iname, index->idxname) == 0)
442 ilist = lnext(ilist);
444 /* ran through entire list? then no name conflict found so done */
448 /* the last one conflicted, so try a new name component */
452 sprintf(name2, "%s_%d", column_name, (pass + 1));
459 * transformCreateStmt -
460 * transforms the "create table" statement
461 * SQL92 allows constraints to be scattered all over, so thumb through
462 * the columns and collect all constraints into one place.
463 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
464 * then expand those into multiple IndexStmt blocks.
465 * - thomas 1997-12-02
468 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
471 int have_pkey = FALSE;
479 Constraint *constraint;
487 q->commandType = CMD_UTILITY;
489 elements = stmt->tableElts;
490 constraints = stmt->constraints;
494 while (elements != NIL)
496 element = lfirst(elements);
497 switch (nodeTag(element))
500 column = (ColumnDef *) element;
501 columns = lappend(columns, column);
503 if (column->is_sequence)
506 CreateSeqStmt *sequence;
508 constraint = makeNode(Constraint);
509 constraint->contype = CONSTR_DEFAULT;
510 constraint->name = makeTableName(stmt->relname, column->colname, "seq", NULL);
511 cstring = palloc(9 + strlen(constraint->name) + 2 + 1);
512 strcpy(cstring, "nextval('");
513 strcat(cstring, constraint->name);
514 strcat(cstring, "')");
515 constraint->def = cstring;
516 constraint->keys = NULL;
518 if (column->constraints != NIL)
519 column->constraints = lappend(column->constraints, constraint);
521 column->constraints = lcons(constraint, NIL);
523 sequence = makeNode(CreateSeqStmt);
524 sequence->seqname = pstrdup(constraint->name);
525 sequence->options = NIL;
527 elog(NOTICE, "CREATE TABLE will create implicit sequence %s for SERIAL column %s.%s",
528 sequence->seqname, stmt->relname, column->colname);
530 ilist = lcons(sequence, NIL);
532 constraint = makeNode(Constraint);
533 constraint->contype = CONSTR_UNIQUE;
534 constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL);
536 column->constraints = lappend(column->constraints, constraint);
539 if (column->constraints != NIL)
541 clist = column->constraints;
544 constraint = lfirst(clist);
545 switch (constraint->contype)
548 if (column->is_not_null)
549 elog(ERROR, "CREATE TABLE/NOT NULL already specified"
550 " for %s.%s", stmt->relname, column->colname);
551 column->is_not_null = TRUE;
555 if (column->defval != NULL)
556 elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
557 " for %s.%s", stmt->relname, column->colname);
558 column->defval = constraint->def;
562 if (constraint->name == NULL)
563 constraint->name = makeTableName(stmt->relname, "pkey", NULL);
564 if (constraint->keys == NIL)
565 constraint->keys = lappend(constraint->keys, column);
566 dlist = lappend(dlist, constraint);
570 if (constraint->name == NULL)
571 constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL);
572 if (constraint->keys == NIL)
573 constraint->keys = lappend(constraint->keys, column);
574 dlist = lappend(dlist, constraint);
578 constraints = lappend(constraints, constraint);
579 if (constraint->name == NULL)
580 constraint->name = makeTableName(stmt->relname, column->colname, NULL);
584 elog(ERROR, "parser: internal error; unrecognized constraint", NULL);
587 clist = lnext(clist);
593 constraint = (Constraint *) element;
594 switch (constraint->contype)
597 if (constraint->name == NULL)
598 constraint->name = makeTableName(stmt->relname, "pkey", NULL);
599 dlist = lappend(dlist, constraint);
604 if (constraint->name == NULL)
605 constraint->name = makeTableName(stmt->relname, "key", NULL);
607 dlist = lappend(dlist, constraint);
611 constraints = lappend(constraints, constraint);
616 elog(ERROR, "parser: internal error; illegal context for constraint", NULL);
619 elog(ERROR, "parser: internal error; unrecognized constraint", NULL);
625 elog(ERROR, "parser: internal error; unrecognized node", NULL);
628 elements = lnext(elements);
631 stmt->tableElts = columns;
632 stmt->constraints = constraints;
634 /* Now run through the "deferred list" to complete the query transformation.
635 * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
636 * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
638 * Note that this code does not currently look for all possible redundant cases
639 * and either ignore or stop with warning. The create might fail later when
640 * names for indices turn out to be redundant, or a user might have specified
641 * extra useless indices which might hurt performance. - thomas 1997-12-08
645 constraint = lfirst(dlist);
646 if (nodeTag(constraint) != T_Constraint)
647 elog(ERROR, "parser: internal error; unrecognized deferred node", NULL);
649 if (constraint->contype == CONSTR_PRIMARY)
652 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
653 " for table %s are not legal", stmt->relname);
657 else if (constraint->contype != CONSTR_UNIQUE)
658 elog(ERROR, "parser: internal error; unrecognized deferred constraint", NULL);
660 index = makeNode(IndexStmt);
662 index->unique = TRUE;
663 if (constraint->name != NULL)
664 index->idxname = constraint->name;
665 else if (constraint->contype == CONSTR_PRIMARY)
668 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple keys for table %s are not legal", stmt->relname);
671 index->idxname = makeTableName(stmt->relname, "pkey", NULL);
674 index->idxname = NULL;
676 index->relname = stmt->relname;
677 index->accessMethod = "btree";
678 index->indexParams = NIL;
679 index->withClause = NIL;
680 index->whereClause = NULL;
682 keys = constraint->keys;
686 columns = stmt->tableElts;
688 while (columns != NIL)
690 column = lfirst(columns);
691 if (strcasecmp(column->colname, key->name) == 0)
695 columns = lnext(columns);
698 elog(ERROR, "parser: column '%s' in key does not exist", key->name);
700 if (constraint->contype == CONSTR_PRIMARY)
701 column->is_not_null = TRUE;
702 iparam = makeNode(IndexElem);
703 iparam->name = strcpy(palloc(strlen(column->colname) + 1), column->colname);
705 iparam->class = NULL;
706 iparam->typename = NULL;
707 index->indexParams = lappend(index->indexParams, iparam);
709 if (index->idxname == NULL)
710 index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
715 if (index->idxname == NULL)
716 elog(ERROR, "parser: unable to construct implicit index for table %s"
717 "; name too long", stmt->relname);
719 elog(NOTICE, "CREATE TABLE/%s will create implicit index %s for table %s",
720 ((constraint->contype == CONSTR_PRIMARY) ? "PRIMARY KEY" : "UNIQUE"),
721 index->idxname, stmt->relname);
723 ilist = lappend(ilist, index);
724 dlist = lnext(dlist);
727 q->utilityStmt = (Node *) stmt;
734 * transformIndexStmt -
735 * transforms the qualification of the index statement
738 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
742 qry = makeNode(Query);
743 qry->commandType = CMD_UTILITY;
745 /* take care of the where clause */
746 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
747 qry->hasSubLinks = pstate->p_hasSubLinks;
749 stmt->rangetable = pstate->p_rtable;
751 qry->utilityStmt = (Node *) stmt;
757 * transformExtendStmt -
758 * transform the qualifications of the Extend Index Statement
762 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
766 qry = makeNode(Query);
767 qry->commandType = CMD_UTILITY;
769 /* take care of the where clause */
770 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
771 qry->hasSubLinks = pstate->p_hasSubLinks;
773 stmt->rangetable = pstate->p_rtable;
775 qry->utilityStmt = (Node *) stmt;
780 * transformRuleStmt -
781 * transform a Create Rule Statement. The actions is a list of parse
782 * trees which is transformed into a list of query trees.
785 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
791 qry = makeNode(Query);
792 qry->commandType = CMD_UTILITY;
795 * 'instead nothing' rules with a qualification need a query a
796 * rangetable so the rewrite handler can add the negated rule
797 * qualification to the original query. We create a query with the new
798 * command type CMD_NOTHING here that is treated special by the
801 if (stmt->actions == NIL)
803 Query *nothing_qry = makeNode(Query);
805 nothing_qry->commandType = CMD_NOTHING;
807 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
809 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
812 nothing_qry->rtable = pstate->p_rtable;
814 stmt->actions = lappend(NIL, nothing_qry);
817 actions = stmt->actions;
820 * transform each statment, like parse_analyze()
822 while (actions != NIL)
826 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
829 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
831 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
834 pstate->p_last_resno = 1;
835 pstate->p_is_rule = true; /* for expand all */
836 pstate->p_hasAggs = false;
838 action = (Query *) lfirst(actions);
839 if (action->commandType != CMD_NOTHING)
840 lfirst(actions) = transformStmt(pstate, lfirst(actions));
841 actions = lnext(actions);
844 /* take care of the where clause */
845 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
846 qry->hasSubLinks = pstate->p_hasSubLinks;
848 qry->utilityStmt = (Node *) stmt;
854 * transformSelectStmt -
855 * transforms a Select Statement
859 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
861 Query *qry = makeNode(Query);
863 qry->commandType = CMD_SELECT;
865 /* set up a range table */
866 makeRangeTable(pstate, NULL, stmt->fromClause);
868 qry->uniqueFlag = stmt->unique;
870 qry->into = stmt->into;
871 qry->isPortal = FALSE;
873 qry->targetList = transformTargetList(pstate, stmt->targetList);
875 qry->qual = transformWhereClause(pstate, stmt->whereClause);
878 * The havingQual has a similar meaning as "qual" in the where
879 * statement. So we can easily use the code from the "where clause"
880 * with some additional traversals done in
881 * .../optimizer/plan/planner.c
883 qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
885 qry->hasSubLinks = pstate->p_hasSubLinks;
887 qry->sortClause = transformSortClause(pstate,
893 qry->groupClause = transformGroupClause(pstate,
896 qry->rtable = pstate->p_rtable;
898 qry->hasAggs = pstate->p_hasAggs;
899 if (pstate->p_hasAggs)
900 parseCheckAggregates(pstate, qry);
903 * The INSERT INTO ... SELECT ... could have a UNION in child, so
904 * unionClause may be false
906 qry->unionall = stmt->unionall;
907 qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
910 * If there is a havingQual but there are no aggregates, then there is
911 * something wrong with the query because having must contain
912 * aggregates in its expressions! Otherwise the query could have been
913 * formulated using the where clause.
915 if ((qry->hasAggs == false) && (qry->havingQual != NULL))
917 elog(ERROR, "This is not a valid having query!");
918 return (Query *) NIL;
921 return (Query *) qry;
925 * transformUpdateStmt -
926 * transforms an update statement
930 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
932 Query *qry = makeNode(Query);
934 qry->commandType = CMD_UPDATE;
935 pstate->p_is_update = true;
938 * the FROM clause is non-standard SQL syntax. We used to be able to
939 * do this with REPLACE in POSTQUEL so we keep the feature.
941 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
943 qry->targetList = transformTargetList(pstate, stmt->targetList);
945 qry->qual = transformWhereClause(pstate, stmt->whereClause);
946 qry->hasSubLinks = pstate->p_hasSubLinks;
948 qry->rtable = pstate->p_rtable;
950 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
952 qry->hasAggs = pstate->p_hasAggs;
953 if (pstate->p_hasAggs)
954 parseCheckAggregates(pstate, qry);
956 return (Query *) qry;
960 * transformCursorStmt -
961 * transform a Create Cursor Statement
965 transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
969 qry = transformSelectStmt(pstate, stmt);
971 qry->into = stmt->portalname;
972 qry->isPortal = TRUE;
973 qry->isBinary = stmt->binary; /* internal portal */