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.75 1998/05/09 23:29:52 thomas 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 AttributeTupleForm *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 = makeNode(TargetEntry);
316 te->resdom = makeResdom(defval[ndef].adnum,
317 att[defval[ndef].adnum - 1]->atttypid,
318 att[defval[ndef].adnum - 1]->atttypmod,
319 pstrdup(nameout(&(att[defval[ndef].adnum - 1]->attname))),
322 te->expr = (Node *) stringToNode(defval[ndef].adbin);
323 qry->targetList = lappend(qry->targetList, te);
327 /* fix where clause */
328 qry->qual = transformWhereClause(pstate, stmt->whereClause);
330 qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
332 qry->hasSubLinks = pstate->p_hasSubLinks;
334 /* now the range table will not change */
335 qry->rtable = pstate->p_rtable;
336 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
338 qry->groupClause = transformGroupClause(pstate,
342 /* fix order clause */
343 qry->sortClause = transformSortClause(pstate,
349 qry->hasAggs = pstate->p_hasAggs;
350 if (pstate->p_hasAggs)
351 parseCheckAggregates(pstate, qry);
353 /* The INSERT INTO ... SELECT ... could have a UNION */
354 qry->unionall = stmt->unionall; /* in child, so unionClause may be
356 qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
358 return (Query *) qry;
363 * Create a table name from a list of fields.
366 makeTableName(void *elem,...)
371 char buf[NAMEDATALEN + 1];
375 va_start(args, elem);
380 /* not enough room for next part? then return nothing */
381 if ((strlen(buf) + strlen(name)) >= (sizeof(buf) - 1))
388 name = va_arg(args, void *);
393 name = palloc(strlen(buf) + 1);
400 CreateIndexName(char *tname, char *cname, char *label, List *indices)
406 char name2[NAMEDATALEN + 1];
408 /* use working storage, since we might be trying several possibilities */
409 strcpy(name2, cname);
410 while (iname == NULL)
412 iname = makeTableName(tname, name2, label, NULL);
413 /* unable to make a name at all? then quit */
420 index = lfirst(ilist);
421 if (strcasecmp(iname, index->idxname) == 0)
424 ilist = lnext(ilist);
426 /* ran through entire list? then no name conflict found so done */
430 /* the last one conflicted, so try a new name component */
434 sprintf(name2, "%s_%d", cname, (pass + 1));
441 * transformCreateStmt -
442 * transforms the "create table" statement
443 * SQL92 allows constraints to be scattered all over, so thumb through
444 * the columns and collect all constraints into one place.
445 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
446 * then expand those into multiple IndexStmt blocks.
447 * - thomas 1997-12-02
450 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
453 int have_pkey = FALSE;
461 Constraint *constraint;
469 q->commandType = CMD_UTILITY;
471 elements = stmt->tableElts;
472 constraints = stmt->constraints;
476 while (elements != NIL)
478 element = lfirst(elements);
479 switch (nodeTag(element))
482 column = (ColumnDef *) element;
483 columns = lappend(columns, column);
484 if (column->constraints != NIL)
486 clist = column->constraints;
489 constraint = lfirst(clist);
490 switch (constraint->contype)
493 if (column->is_not_null)
494 elog(ERROR, "CREATE TABLE/NOT NULL already specified"
495 " for %s.%s", stmt->relname, column->colname);
496 column->is_not_null = TRUE;
500 if (column->defval != NULL)
501 elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
502 " for %s.%s", stmt->relname, column->colname);
503 column->defval = constraint->def;
507 if (constraint->name == NULL)
508 constraint->name = makeTableName(stmt->relname, "pkey", NULL);
509 if (constraint->keys == NIL)
510 constraint->keys = lappend(constraint->keys, column);
511 dlist = lappend(dlist, constraint);
515 if (constraint->name == NULL)
516 constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL);
517 if (constraint->keys == NIL)
518 constraint->keys = lappend(constraint->keys, column);
519 dlist = lappend(dlist, constraint);
523 constraints = lappend(constraints, constraint);
524 if (constraint->name == NULL)
525 constraint->name = makeTableName(stmt->relname, column->colname, NULL);
529 elog(ERROR, "parser: internal error; unrecognized constraint", NULL);
532 clist = lnext(clist);
538 constraint = (Constraint *) element;
539 switch (constraint->contype)
542 if (constraint->name == NULL)
543 constraint->name = makeTableName(stmt->relname, "pkey", NULL);
544 dlist = lappend(dlist, constraint);
549 if (constraint->name == NULL)
550 constraint->name = makeTableName(stmt->relname, "key", NULL);
552 dlist = lappend(dlist, constraint);
556 constraints = lappend(constraints, constraint);
561 elog(ERROR, "parser: internal error; illegal context for constraint", NULL);
564 elog(ERROR, "parser: internal error; unrecognized constraint", NULL);
570 elog(ERROR, "parser: internal error; unrecognized node", NULL);
573 elements = lnext(elements);
576 stmt->tableElts = columns;
577 stmt->constraints = constraints;
579 /* Now run through the "deferred list" to complete the query transformation.
580 * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
581 * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
583 * Note that this code does not currently look for all possible redundant cases
584 * and either ignore or stop with warning. The create might fail later when
585 * names for indices turn out to be redundant, or a user might have specified
586 * extra useless indices which might hurt performance. - thomas 1997-12-08
591 constraint = lfirst(dlist);
592 if (nodeTag(constraint) != T_Constraint)
593 elog(ERROR, "parser: internal error; unrecognized deferred node", NULL);
595 if (constraint->contype == CONSTR_PRIMARY)
598 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
599 " for table %s are not legal", stmt->relname);
603 else if (constraint->contype != CONSTR_UNIQUE)
604 elog(ERROR, "parser: internal error; unrecognized deferred constraint", NULL);
606 index = makeNode(IndexStmt);
608 index->unique = TRUE;
609 if (constraint->name != NULL)
610 index->idxname = constraint->name;
611 else if (constraint->contype == CONSTR_PRIMARY)
614 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple keys for table %s are not legal", stmt->relname);
617 index->idxname = makeTableName(stmt->relname, "pkey", NULL);
620 index->idxname = NULL;
622 index->relname = stmt->relname;
623 index->accessMethod = "btree";
624 index->indexParams = NIL;
625 index->withClause = NIL;
626 index->whereClause = NULL;
628 keys = constraint->keys;
632 columns = stmt->tableElts;
634 while (columns != NIL)
636 column = lfirst(columns);
637 if (strcasecmp(column->colname, key->name) == 0)
641 columns = lnext(columns);
644 elog(ERROR, "parser: column '%s' in key does not exist", key->name);
646 if (constraint->contype == CONSTR_PRIMARY)
647 column->is_not_null = TRUE;
648 iparam = makeNode(IndexElem);
649 iparam->name = strcpy(palloc(strlen(column->colname) + 1), column->colname);
651 iparam->class = NULL;
652 iparam->tname = NULL;
653 index->indexParams = lappend(index->indexParams, iparam);
655 if (index->idxname == NULL)
656 index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
661 if (index->idxname == NULL)
662 elog(ERROR, "parser: unable to construct implicit index for table %s"
663 "; name too long", stmt->relname);
665 elog(NOTICE, "CREATE TABLE/%s will create implicit index %s for table %s",
666 ((constraint->contype == CONSTR_PRIMARY) ? "PRIMARY KEY" : "UNIQUE"),
667 index->idxname, stmt->relname);
669 ilist = lappend(ilist, index);
670 dlist = lnext(dlist);
673 q->utilityStmt = (Node *) stmt;
680 * transformIndexStmt -
681 * transforms the qualification of the index statement
684 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
688 qry = makeNode(Query);
689 qry->commandType = CMD_UTILITY;
691 /* take care of the where clause */
692 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
693 qry->hasSubLinks = pstate->p_hasSubLinks;
695 stmt->rangetable = pstate->p_rtable;
697 qry->utilityStmt = (Node *) stmt;
703 * transformExtendStmt -
704 * transform the qualifications of the Extend Index Statement
708 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
712 qry = makeNode(Query);
713 qry->commandType = CMD_UTILITY;
715 /* take care of the where clause */
716 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
717 qry->hasSubLinks = pstate->p_hasSubLinks;
719 stmt->rangetable = pstate->p_rtable;
721 qry->utilityStmt = (Node *) stmt;
726 * transformRuleStmt -
727 * transform a Create Rule Statement. The actions is a list of parse
728 * trees which is transformed into a list of query trees.
731 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
736 qry = makeNode(Query);
737 qry->commandType = CMD_UTILITY;
739 actions = stmt->actions;
742 * transform each statment, like parse_analyze()
744 while (actions != NIL)
748 * NOTE: 'CURRENT' must always have a varno equal to 1 and 'NEW'
751 addRangeTableEntry(pstate, stmt->object->relname, "*CURRENT*",
753 addRangeTableEntry(pstate, stmt->object->relname, "*NEW*",
756 pstate->p_last_resno = 1;
757 pstate->p_is_rule = true; /* for expand all */
758 pstate->p_hasAggs = false;
760 lfirst(actions) = transformStmt(pstate, lfirst(actions));
761 actions = lnext(actions);
764 /* take care of the where clause */
765 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
766 qry->hasSubLinks = pstate->p_hasSubLinks;
768 qry->utilityStmt = (Node *) stmt;
774 * transformSelectStmt -
775 * transforms a Select Statement
779 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
781 Query *qry = makeNode(Query);
783 qry->commandType = CMD_SELECT;
785 /* set up a range table */
786 makeRangeTable(pstate, NULL, stmt->fromClause);
788 qry->uniqueFlag = stmt->unique;
790 qry->into = stmt->into;
791 qry->isPortal = FALSE;
793 qry->targetList = transformTargetList(pstate, stmt->targetList);
795 qry->qual = transformWhereClause(pstate, stmt->whereClause);
797 qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
799 qry->hasSubLinks = pstate->p_hasSubLinks;
801 qry->sortClause = transformSortClause(pstate,
807 qry->groupClause = transformGroupClause(pstate,
810 qry->rtable = pstate->p_rtable;
812 qry->hasAggs = pstate->p_hasAggs;
813 if (pstate->p_hasAggs)
814 parseCheckAggregates(pstate, qry);
816 qry->unionall = stmt->unionall; /* in child, so unionClause may be
818 qry->unionClause = transformUnionClause(stmt->unionClause, qry->targetList);
820 return (Query *) qry;
824 * transformUpdateStmt -
825 * transforms an update statement
829 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
831 Query *qry = makeNode(Query);
833 qry->commandType = CMD_UPDATE;
834 pstate->p_is_update = true;
837 * the FROM clause is non-standard SQL syntax. We used to be able to
838 * do this with REPLACE in POSTQUEL so we keep the feature.
840 makeRangeTable(pstate, stmt->relname, stmt->fromClause);
842 qry->targetList = transformTargetList(pstate, stmt->targetList);
844 qry->qual = transformWhereClause(pstate, stmt->whereClause);
845 qry->hasSubLinks = pstate->p_hasSubLinks;
847 qry->rtable = pstate->p_rtable;
849 qry->resultRelation = refnameRangeTablePosn(pstate, stmt->relname, NULL);
851 qry->hasAggs = pstate->p_hasAggs;
852 if (pstate->p_hasAggs)
853 parseCheckAggregates(pstate, qry);
855 return (Query *) qry;
859 * transformCursorStmt -
860 * transform a Create Cursor Statement
864 transformCursorStmt(ParseState *pstate, SelectStmt *stmt)
868 qry = transformSelectStmt(pstate, stmt);
870 qry->into = stmt->portalname;
871 qry->isPortal = TRUE;
872 qry->isBinary = stmt->binary; /* internal portal */