1 /*-------------------------------------------------------------------------
4 * transform the parse tree into a query tree
6 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
9 * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.238 2002/07/12 18:43:17 tgl Exp $
11 *-------------------------------------------------------------------------
16 #include "access/heapam.h"
17 #include "catalog/catname.h"
18 #include "catalog/heap.h"
19 #include "catalog/index.h"
20 #include "catalog/namespace.h"
21 #include "catalog/pg_index.h"
22 #include "catalog/pg_type.h"
23 #include "nodes/makefuncs.h"
24 #include "parser/analyze.h"
25 #include "parser/gramparse.h"
26 #include "parser/parsetree.h"
27 #include "parser/parse_agg.h"
28 #include "parser/parse_clause.h"
29 #include "parser/parse_coerce.h"
30 #include "parser/parse_expr.h"
31 #include "parser/parse_oper.h"
32 #include "parser/parse_relation.h"
33 #include "parser/parse_target.h"
34 #include "parser/parse_type.h"
35 #include "parser/parse_expr.h"
36 #include "rewrite/rewriteManip.h"
37 #include "utils/builtins.h"
38 #include "utils/fmgroids.h"
39 #include "utils/lsyscache.h"
40 #include "utils/relcache.h"
41 #include "utils/syscache.h"
43 #include "mb/pg_wchar.h"
47 /* State shared by transformCreateSchemaStmt and its subroutines */
50 const char *stmtType; /* "CREATE SCHEMA" or "ALTER SCHEMA" */
51 char *schemaname; /* name of schema */
52 char *authid; /* owner of schema */
53 List *tables; /* CREATE TABLE items */
54 List *views; /* CREATE VIEW items */
55 List *grants; /* GRANT items */
56 List *fwconstraints; /* Forward referencing FOREIGN KEY constraints */
57 List *alters; /* Generated ALTER items (from the above) */
58 List *ixconstraints; /* index-creating constraints */
59 List *blist; /* "before list" of things to do before
60 * creating the schema */
61 List *alist; /* "after list" of things to do after
62 * creating the schema */
63 } CreateSchemaStmtContext;
65 /* State shared by transformCreateStmt and its subroutines */
68 const char *stmtType; /* "CREATE TABLE" or "ALTER TABLE" */
69 RangeVar *relation; /* relation to create */
70 List *inhRelations; /* relations to inherit from */
71 bool hasoids; /* does relation have an OID column? */
72 Oid relOid; /* OID of table, if ALTER TABLE case */
73 List *columns; /* ColumnDef items */
74 List *ckconstraints; /* CHECK constraints */
75 List *fkconstraints; /* FOREIGN KEY constraints */
76 List *ixconstraints; /* index-creating constraints */
77 List *blist; /* "before list" of things to do before
78 * creating the table */
79 List *alist; /* "after list" of things to do after
80 * creating the table */
81 IndexStmt *pkey; /* PRIMARY KEY index, if any */
85 static Query *transformStmt(ParseState *pstate, Node *stmt,
86 List **extras_before, List **extras_after);
87 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
88 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
89 List **extras_before, List **extras_after);
90 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
91 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt,
92 List **extras_before, List **extras_after);
93 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
94 static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
95 static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
96 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
97 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
98 List **extras_before, List **extras_after);
99 static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
100 List **extras_before, List **extras_after);
101 static void transformColumnDefinition(ParseState *pstate,
102 CreateStmtContext *cxt,
104 static void transformTableConstraint(ParseState *pstate,
105 CreateStmtContext *cxt,
106 Constraint *constraint);
107 static void transformIndexConstraints(ParseState *pstate,
108 CreateStmtContext *cxt);
109 static void transformFKConstraints(ParseState *pstate,
110 CreateStmtContext *cxt);
111 static void applyColumnNames(List *dst, List *src);
112 static List *getSetColTypes(ParseState *pstate, Node *node);
113 static void transformForUpdate(Query *qry, List *forUpdate);
114 static void transformConstraintAttrs(List *constraintList);
115 static void transformColumnType(ParseState *pstate, ColumnDef *column);
116 static void transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid);
117 static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid);
118 static bool relationHasPrimaryKey(Oid relationOid);
119 static Oid transformFkeyGetColType(CreateStmtContext *cxt, char *colname);
120 static void release_pstate_resources(ParseState *pstate);
121 static FromExpr *makeFromExpr(List *fromlist, Node *quals);
127 * analyze a raw parse tree and transform it to Query form.
129 * The result is a List of Query nodes (we need a list since some commands
130 * produce multiple Queries). Optimizable statements require considerable
131 * transformation, while many utility-type statements are simply hung off
132 * a dummy CMD_UTILITY Query node.
135 parse_analyze(Node *parseTree, ParseState *parentParseState)
138 ParseState *pstate = make_parsestate(parentParseState);
139 /* Lists to return extra commands from transformation */
140 List *extras_before = NIL;
141 List *extras_after = NIL;
145 query = transformStmt(pstate, parseTree, &extras_before, &extras_after);
146 release_pstate_resources(pstate);
148 while (extras_before != NIL)
150 result = nconc(result, parse_analyze(lfirst(extras_before), pstate));
151 extras_before = lnext(extras_before);
154 result = lappend(result, query);
156 while (extras_after != NIL)
158 result = nconc(result, parse_analyze(lfirst(extras_after), pstate));
159 extras_after = lnext(extras_after);
163 * Make sure that only the original query is marked original.
164 * We have to do this explicitly since recursive calls of parse_analyze
165 * will have set originalQuery in some of the added-on queries.
167 foreach(listscan, result)
169 Query *q = lfirst(listscan);
171 q->originalQuery = (q == query);
180 release_pstate_resources(ParseState *pstate)
182 if (pstate->p_target_relation != NULL)
183 heap_close(pstate->p_target_relation, NoLock);
184 pstate->p_target_relation = NULL;
185 pstate->p_target_rangetblentry = NULL;
190 * transform a Parse tree into a Query tree.
193 transformStmt(ParseState *pstate, Node *parseTree,
194 List **extras_before, List **extras_after)
196 Query *result = NULL;
198 switch (nodeTag(parseTree))
201 * Non-optimizable statements
204 result = transformCreateStmt(pstate, (CreateStmt *) parseTree,
205 extras_before, extras_after);
209 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
213 result = transformRuleStmt(pstate, (RuleStmt *) parseTree,
214 extras_before, extras_after);
219 ViewStmt *n = (ViewStmt *) parseTree;
221 n->query = transformStmt(pstate, (Node *) n->query,
222 extras_before, extras_after);
225 * If a list of column names was given, run through and
226 * insert these into the actual query tree. - thomas
229 * Outer loop is over targetlist to make it easier to skip
230 * junk targetlist entries.
232 if (n->aliases != NIL)
234 List *aliaslist = n->aliases;
237 foreach(targetList, n->query->targetList)
239 TargetEntry *te = (TargetEntry *) lfirst(targetList);
243 Assert(IsA(te, TargetEntry));
245 Assert(IsA(rd, Resdom));
246 if (rd->resjunk) /* junk columns don't get
249 id = (Ident *) lfirst(aliaslist);
250 Assert(IsA(id, Ident));
251 rd->resname = pstrdup(id->name);
252 aliaslist = lnext(aliaslist);
253 if (aliaslist == NIL)
254 break; /* done assigning aliases */
257 if (aliaslist != NIL)
258 elog(ERROR, "CREATE VIEW specifies more column names than columns");
260 result = makeNode(Query);
261 result->commandType = CMD_UTILITY;
262 result->utilityStmt = (Node *) n;
268 ExplainStmt *n = (ExplainStmt *) parseTree;
270 result = makeNode(Query);
271 result->commandType = CMD_UTILITY;
272 n->query = transformStmt(pstate, (Node *) n->query,
273 extras_before, extras_after);
274 result->utilityStmt = (Node *) parseTree;
278 case T_AlterTableStmt:
279 result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree,
280 extras_before, extras_after);
284 * Optimizable statements
287 result = transformInsertStmt(pstate, (InsertStmt *) parseTree,
288 extras_before, extras_after);
292 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
296 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
300 if (((SelectStmt *) parseTree)->op == SETOP_NONE)
301 result = transformSelectStmt(pstate,
302 (SelectStmt *) parseTree);
304 result = transformSetOperationStmt(pstate,
305 (SelectStmt *) parseTree);
311 * other statements don't require any transformation-- just
312 * return the original parsetree, yea!
314 result = makeNode(Query);
315 result->commandType = CMD_UTILITY;
316 result->utilityStmt = (Node *) parseTree;
323 * transformDeleteStmt -
324 * transforms a Delete Statement
327 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
329 Query *qry = makeNode(Query);
332 qry->commandType = CMD_DELETE;
334 /* set up range table with just the result rel */
335 qry->resultRelation = setTargetTable(pstate, stmt->relation,
336 interpretInhOption(stmt->relation->inhOpt),
339 qry->distinctClause = NIL;
341 /* fix where clause */
342 qual = transformWhereClause(pstate, stmt->whereClause);
344 /* done building the range table and jointree */
345 qry->rtable = pstate->p_rtable;
346 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
348 qry->hasSubLinks = pstate->p_hasSubLinks;
349 qry->hasAggs = pstate->p_hasAggs;
350 if (pstate->p_hasAggs)
351 parseCheckAggregates(pstate, qry, qual);
357 * transformInsertStmt -
358 * transform an Insert Statement
361 transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
362 List **extras_before, List **extras_after)
364 Query *qry = makeNode(Query);
372 qry->commandType = CMD_INSERT;
373 pstate->p_is_insert = true;
376 * If a non-nil rangetable/namespace was passed in, and we are doing
377 * INSERT/SELECT, arrange to pass the rangetable/namespace down to the
378 * SELECT. This can only happen if we are inside a CREATE RULE, and
379 * in that case we want the rule's OLD and NEW rtable entries to
380 * appear as part of the SELECT's rtable, not as outer references for
381 * it. (Kluge!) The SELECT's joinlist is not affected however. We
382 * must do this before adding the target table to the INSERT's rtable.
384 if (stmt->selectStmt)
386 sub_rtable = pstate->p_rtable;
387 pstate->p_rtable = NIL;
388 sub_namespace = pstate->p_namespace;
389 pstate->p_namespace = NIL;
393 sub_rtable = NIL; /* not used, but keep compiler quiet */
398 * Must get write lock on INSERT target table before scanning SELECT,
399 * else we will grab the wrong kind of initial lock if the target
400 * table is also mentioned in the SELECT part. Note that the target
401 * table is not added to the joinlist or namespace.
403 qry->resultRelation = setTargetTable(pstate, stmt->relation,
407 * Is it INSERT ... SELECT or INSERT ... VALUES?
409 if (stmt->selectStmt)
411 ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
417 * Process the source SELECT.
419 * It is important that this be handled just like a standalone
420 * SELECT; otherwise the behavior of SELECT within INSERT might be
421 * different from a stand-alone SELECT. (Indeed, Postgres up
422 * through 6.5 had bugs of just that nature...)
424 sub_pstate->p_rtable = sub_rtable;
425 sub_pstate->p_namespace = sub_namespace;
428 * Note: we are not expecting that extras_before and extras_after
429 * are going to be used by the transformation of the SELECT statement.
431 selectQuery = transformStmt(sub_pstate, stmt->selectStmt,
432 extras_before, extras_after);
434 release_pstate_resources(sub_pstate);
437 Assert(IsA(selectQuery, Query));
438 Assert(selectQuery->commandType == CMD_SELECT);
439 if (selectQuery->into || selectQuery->isPortal)
440 elog(ERROR, "INSERT ... SELECT may not specify INTO");
443 * Make the source be a subquery in the INSERT's rangetable, and
444 * add it to the INSERT's joinlist.
446 rte = addRangeTableEntryForSubquery(pstate,
448 makeAlias("*SELECT*", NIL),
450 rtr = makeNode(RangeTblRef);
451 /* assume new rte is at end */
452 rtr->rtindex = length(pstate->p_rtable);
453 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
454 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
457 * Generate a targetlist for the INSERT that selects all the
458 * non-resjunk columns from the subquery. (We need this to be
459 * separate from the subquery's tlist because we may add columns,
460 * insert datatype coercions, etc.)
462 * HACK: constants in the INSERT's targetlist are copied up as-is
463 * rather than being referenced as subquery outputs. This is
464 * mainly to ensure that when we try to coerce them to the target
465 * column's datatype, the right things happen for UNKNOWN
466 * constants. Otherwise this fails: INSERT INTO foo SELECT 'bar',
469 qry->targetList = NIL;
470 foreach(tl, selectQuery->targetList)
472 TargetEntry *tle = (TargetEntry *) lfirst(tl);
473 Resdom *resnode = tle->resdom;
476 if (resnode->resjunk)
478 if (tle->expr && IsA(tle->expr, Const))
481 expr = (Node *) makeVar(rtr->rtindex,
486 resnode = copyObject(resnode);
487 resnode->resno = (AttrNumber) pstate->p_last_resno++;
488 qry->targetList = lappend(qry->targetList,
489 makeTargetEntry(resnode, expr));
495 * For INSERT ... VALUES, transform the given list of values to
496 * form a targetlist for the INSERT.
498 qry->targetList = transformTargetList(pstate, stmt->targetList);
502 * Now we are done with SELECT-like processing, and can get on with
503 * transforming the target list to match the INSERT target columns.
506 /* Prepare to assign non-conflicting resnos to resjunk attributes */
507 if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
508 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
510 /* Validate stmt->cols list, or build default list if no list given */
511 icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
514 * Prepare columns for assignment to target table.
517 foreach(tl, qry->targetList)
519 TargetEntry *tle = (TargetEntry *) lfirst(tl);
522 if (icolumns == NIL || attnos == NIL)
523 elog(ERROR, "INSERT has more expressions than target columns");
524 col = (ResTarget *) lfirst(icolumns);
527 * When the value is to be set to the column default we can simply
528 * drop it now and handle it later on using methods for missing
531 if (!IsA(tle, InsertDefault))
533 Assert(IsA(col, ResTarget));
534 Assert(!tle->resdom->resjunk);
535 updateTargetListEntry(pstate, tle, col->name, lfirsti(attnos),
540 icolumns = lremove(icolumns, icolumns);
541 attnos = lremove(attnos, attnos);
542 qry->targetList = lremove(tle, qry->targetList);
545 icolumns = lnext(icolumns);
546 attnos = lnext(attnos);
550 * Ensure that the targetlist has the same number of entries
551 * that were present in the columns list. Don't do the check
552 * for select statements.
554 if (stmt->cols != NIL && (icolumns != NIL || attnos != NIL))
555 elog(ERROR, "INSERT has more target columns than expressions");
557 /* done building the range table and jointree */
558 qry->rtable = pstate->p_rtable;
559 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
561 qry->hasSubLinks = pstate->p_hasSubLinks;
562 qry->hasAggs = pstate->p_hasAggs;
563 if (pstate->p_hasAggs)
564 parseCheckAggregates(pstate, qry, NULL);
572 * Create a name for an implicitly created index, sequence, constraint, etc.
574 * The parameters are: the original table name, the original field name, and
575 * a "type" string (such as "seq" or "pkey"). The field name and/or type
576 * can be NULL if not relevant.
578 * The result is a palloc'd string.
580 * The basic result we want is "name1_name2_type", omitting "_name2" or
581 * "_type" when those parameters are NULL. However, we must generate
582 * a name with less than NAMEDATALEN characters! So, we truncate one or
583 * both names if necessary to make a short-enough string. The type part
584 * is never truncated (so it had better be reasonably short).
586 * To reduce the probability of collisions, we might someday add more
587 * smarts to this routine, like including some "hash" characters computed
588 * from the truncated characters. Currently it seems best to keep it simple,
589 * so that the generated names are easily predictable by a person.
592 makeObjectName(char *name1, char *name2, char *typename)
595 int overhead = 0; /* chars needed for type and underscores */
596 int availchars; /* chars available for name(s) */
597 int name1chars; /* chars allocated to name1 */
598 int name2chars; /* chars allocated to name2 */
601 name1chars = strlen(name1);
604 name2chars = strlen(name2);
605 overhead++; /* allow for separating underscore */
610 overhead += strlen(typename) + 1;
612 availchars = NAMEDATALEN - 1 - overhead;
615 * If we must truncate, preferentially truncate the longer name. This
616 * logic could be expressed without a loop, but it's simple and
619 while (name1chars + name2chars > availchars)
621 if (name1chars > name2chars)
629 name1chars = pg_mbcliplen(name1, name1chars, name1chars);
631 name2chars = pg_mbcliplen(name2, name2chars, name2chars);
634 /* Now construct the string using the chosen lengths */
635 name = palloc(name1chars + name2chars + overhead + 1);
636 strncpy(name, name1, name1chars);
641 strncpy(name + ndx, name2, name2chars);
647 strcpy(name + ndx, typename);
656 CreateIndexName(char *table_name, char *column_name,
657 char *label, List *indices)
662 char typename[NAMEDATALEN];
665 * The type name for makeObjectName is label, or labelN if that's
666 * necessary to prevent collisions among multiple indexes for the same
667 * table. Note there is no check for collisions with already-existing
668 * indexes, only among the indexes we're about to create now; this
669 * ought to be improved someday.
671 strcpy(typename, label);
675 iname = makeObjectName(table_name, column_name, typename);
677 foreach(ilist, indices)
679 IndexStmt *index = lfirst(ilist);
681 if (index->idxname != NULL &&
682 strcmp(iname, index->idxname) == 0)
685 /* ran through entire list? then no name conflict found so done */
689 /* found a conflict, so try a new name component */
691 sprintf(typename, "%s%d", label, ++pass);
698 * transformCreateStmt -
699 * transforms the "create table" statement
700 * SQL92 allows constraints to be scattered all over, so thumb through
701 * the columns and collect all constraints into one place.
702 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
703 * then expand those into multiple IndexStmt blocks.
704 * - thomas 1997-12-02
707 transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
708 List **extras_before, List **extras_after)
710 CreateStmtContext cxt;
714 cxt.stmtType = "CREATE TABLE";
715 cxt.relation = stmt->relation;
716 cxt.inhRelations = stmt->inhRelations;
717 cxt.hasoids = stmt->hasoids;
718 cxt.relOid = InvalidOid;
720 cxt.ckconstraints = NIL;
721 cxt.fkconstraints = NIL;
722 cxt.ixconstraints = NIL;
728 * Run through each primary element in the table creation clause.
729 * Separate column defs from constraints, and do preliminary analysis.
731 foreach(elements, stmt->tableElts)
733 Node *element = lfirst(elements);
735 switch (nodeTag(element))
738 transformColumnDefinition(pstate, &cxt,
739 (ColumnDef *) element);
743 transformTableConstraint(pstate, &cxt,
744 (Constraint *) element);
748 /* No pre-transformation needed */
749 cxt.fkconstraints = lappend(cxt.fkconstraints, element);
753 elog(ERROR, "parser: unrecognized node (internal error)");
757 Assert(stmt->constraints == NIL);
760 * Postprocess constraints that give rise to index definitions.
762 transformIndexConstraints(pstate, &cxt);
765 * Postprocess foreign-key constraints.
767 transformFKConstraints(pstate, &cxt);
773 q->commandType = CMD_UTILITY;
774 q->utilityStmt = (Node *) stmt;
775 stmt->tableElts = cxt.columns;
776 stmt->constraints = cxt.ckconstraints;
777 *extras_before = nconc (*extras_before, cxt.blist);
778 *extras_after = nconc (cxt.alist, *extras_after);
784 transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
789 Constraint *constraint;
793 cxt->columns = lappend(cxt->columns, column);
795 /* Check for SERIAL pseudo-types */
797 if (length(column->typename->names) == 1)
799 char *typname = strVal(lfirst(column->typename->names));
801 if (strcmp(typname, "serial") == 0 ||
802 strcmp(typname, "serial4") == 0)
805 column->typename->names = NIL;
806 column->typename->typeid = INT4OID;
808 else if (strcmp(typname, "bigserial") == 0 ||
809 strcmp(typname, "serial8") == 0)
812 column->typename->names = NIL;
813 column->typename->typeid = INT8OID;
817 /* Do necessary work on the column type declaration */
818 transformColumnType(pstate, column);
820 /* Special actions for SERIAL pseudo-types */
827 FuncCall *funccallnode;
828 CreateSeqStmt *seqstmt;
831 * Determine name and namespace to use for the sequence.
833 sname = makeObjectName(cxt->relation->relname, column->colname, "seq");
834 snamespace = get_namespace_name(RangeVarGetCreationNamespace(cxt->relation));
836 elog(NOTICE, "%s will create implicit sequence '%s' for SERIAL column '%s.%s'",
837 cxt->stmtType, sname, cxt->relation->relname, column->colname);
840 * Build a CREATE SEQUENCE command to create the sequence object,
841 * and add it to the list of things to be done before this
842 * CREATE/ALTER TABLE.
844 seqstmt = makeNode(CreateSeqStmt);
845 seqstmt->sequence = makeRangeVar(snamespace, sname);
846 seqstmt->options = NIL;
848 cxt->blist = lappend(cxt->blist, seqstmt);
851 * Create appropriate constraints for SERIAL. We do this in full,
852 * rather than shortcutting, so that we will detect any
853 * conflicting constraints the user wrote (like a different
856 * Create an expression tree representing the function call
857 * nextval('"sequencename"')
859 qstring = quote_qualified_identifier(snamespace, sname);
860 snamenode = makeNode(A_Const);
861 snamenode->val.type = T_String;
862 snamenode->val.val.str = qstring;
863 funccallnode = makeNode(FuncCall);
864 funccallnode->funcname = SystemFuncName("nextval");
865 funccallnode->args = makeList1(snamenode);
866 funccallnode->agg_star = false;
867 funccallnode->agg_distinct = false;
869 constraint = makeNode(Constraint);
870 constraint->contype = CONSTR_DEFAULT;
871 constraint->name = sname;
872 constraint->raw_expr = (Node *) funccallnode;
873 constraint->cooked_expr = NULL;
874 constraint->keys = NIL;
875 column->constraints = lappend(column->constraints, constraint);
877 constraint = makeNode(Constraint);
878 constraint->contype = CONSTR_UNIQUE;
879 constraint->name = NULL; /* assign later */
880 column->constraints = lappend(column->constraints, constraint);
882 constraint = makeNode(Constraint);
883 constraint->contype = CONSTR_NOTNULL;
884 column->constraints = lappend(column->constraints, constraint);
887 /* Process column constraints, if any... */
888 transformConstraintAttrs(column->constraints);
890 saw_nullable = false;
892 foreach(clist, column->constraints)
894 constraint = lfirst(clist);
897 * If this column constraint is a FOREIGN KEY constraint, then we
898 * fill in the current attributes name and throw it into the list
899 * of FK constraints to be processed later.
901 if (IsA(constraint, FkConstraint))
903 FkConstraint *fkconstraint = (FkConstraint *) constraint;
904 Ident *id = makeNode(Ident);
906 id->name = column->colname;
907 fkconstraint->fk_attrs = makeList1(id);
909 cxt->fkconstraints = lappend(cxt->fkconstraints, fkconstraint);
913 Assert(IsA(constraint, Constraint));
915 switch (constraint->contype)
918 if (saw_nullable && column->is_not_null)
919 elog(ERROR, "%s/(NOT) NULL conflicting declaration for '%s.%s'",
920 cxt->stmtType, (cxt->relation)->relname, column->colname);
921 column->is_not_null = FALSE;
926 if (saw_nullable && !column->is_not_null)
927 elog(ERROR, "%s/(NOT) NULL conflicting declaration for '%s.%s'",
928 cxt->stmtType, (cxt->relation)->relname, column->colname);
929 column->is_not_null = TRUE;
934 if (column->raw_default != NULL)
935 elog(ERROR, "%s/DEFAULT multiple values specified for '%s.%s'",
936 cxt->stmtType, (cxt->relation)->relname, column->colname);
937 column->raw_default = constraint->raw_expr;
938 Assert(constraint->cooked_expr == NULL);
942 if (constraint->name == NULL)
943 constraint->name = makeObjectName((cxt->relation)->relname,
946 if (constraint->keys == NIL)
948 key = makeNode(Ident);
949 key->name = pstrdup(column->colname);
950 constraint->keys = makeList1(key);
952 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
956 if (constraint->name == NULL)
957 constraint->name = makeObjectName((cxt->relation)->relname,
960 if (constraint->keys == NIL)
962 key = makeNode(Ident);
963 key->name = pstrdup(column->colname);
964 constraint->keys = makeList1(key);
966 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
970 if (constraint->name == NULL)
971 constraint->name = makeObjectName((cxt->relation)->relname,
974 cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
977 case CONSTR_ATTR_DEFERRABLE:
978 case CONSTR_ATTR_NOT_DEFERRABLE:
979 case CONSTR_ATTR_DEFERRED:
980 case CONSTR_ATTR_IMMEDIATE:
981 /* transformConstraintAttrs took care of these */
985 elog(ERROR, "parser: unrecognized constraint (internal error)");
992 transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
993 Constraint *constraint)
995 switch (constraint->contype)
998 if (constraint->name == NULL)
999 constraint->name = makeObjectName((cxt->relation)->relname,
1002 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
1006 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
1010 cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
1014 case CONSTR_NOTNULL:
1015 case CONSTR_DEFAULT:
1016 case CONSTR_ATTR_DEFERRABLE:
1017 case CONSTR_ATTR_NOT_DEFERRABLE:
1018 case CONSTR_ATTR_DEFERRED:
1019 case CONSTR_ATTR_IMMEDIATE:
1020 elog(ERROR, "parser: illegal context for constraint (internal error)");
1024 elog(ERROR, "parser: unrecognized constraint (internal error)");
1030 transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
1038 List *indexlist = NIL;
1041 * Run through the constraints that need to generate an index. For
1042 * PRIMARY KEY, mark each column as NOT NULL and create an index. For
1043 * UNIQUE, create an index as for PRIMARY KEY, but do not insist on
1046 foreach(listptr, cxt->ixconstraints)
1048 Constraint *constraint = lfirst(listptr);
1050 Assert(IsA(constraint, Constraint));
1051 Assert((constraint->contype == CONSTR_PRIMARY)
1052 || (constraint->contype == CONSTR_UNIQUE));
1054 index = makeNode(IndexStmt);
1056 index->unique = true;
1057 index->primary = (constraint->contype == CONSTR_PRIMARY);
1060 /* In ALTER TABLE case, a primary index might already exist */
1061 if (cxt->pkey != NULL ||
1062 (OidIsValid(cxt->relOid) &&
1063 relationHasPrimaryKey(cxt->relOid)))
1064 elog(ERROR, "%s / PRIMARY KEY multiple primary keys"
1065 " for table '%s' are not allowed",
1066 cxt->stmtType, (cxt->relation)->relname);
1069 index->isconstraint = true;
1071 if (constraint->name != NULL)
1072 index->idxname = pstrdup(constraint->name);
1073 else if (constraint->contype == CONSTR_PRIMARY)
1074 index->idxname = makeObjectName((cxt->relation)->relname, NULL, "pkey");
1076 index->idxname = NULL; /* will set it later */
1078 index->relation = cxt->relation;
1079 index->accessMethod = DEFAULT_INDEX_TYPE;
1080 index->indexParams = NIL;
1081 index->whereClause = NULL;
1084 * Make sure referenced keys exist. If we are making a PRIMARY
1085 * KEY index, also make sure they are NOT NULL.
1087 foreach(keys, constraint->keys)
1089 Ident *key = (Ident *) lfirst(keys);
1092 Assert(IsA(key, Ident));
1094 foreach(columns, cxt->columns)
1096 column = lfirst(columns);
1097 Assert(IsA(column, ColumnDef));
1098 if (strcmp(column->colname, key->name) == 0)
1106 /* found column in the new table; force it to be NOT NULL */
1107 if (constraint->contype == CONSTR_PRIMARY)
1108 column->is_not_null = TRUE;
1110 else if (SystemAttributeByName(key->name, cxt->hasoids) != NULL)
1113 * column will be a system column in the new table, so
1114 * accept it. System columns can't ever be null, so no
1115 * need to worry about PRIMARY/NOT NULL constraint.
1119 else if (cxt->inhRelations)
1121 /* try inherited tables */
1124 foreach(inher, cxt->inhRelations)
1126 RangeVar *inh = lfirst(inher);
1130 Assert(IsA(inh, RangeVar));
1131 rel = heap_openrv(inh, AccessShareLock);
1132 if (rel->rd_rel->relkind != RELKIND_RELATION)
1133 elog(ERROR, "inherited table \"%s\" is not a relation",
1135 for (count = 0; count < rel->rd_att->natts; count++)
1137 Form_pg_attribute inhattr = rel->rd_att->attrs[count];
1138 char *inhname = NameStr(inhattr->attname);
1140 if (strcmp(key->name, inhname) == 0)
1145 * If the column is inherited, we currently
1146 * have no easy way to force it to be NOT
1147 * NULL. Only way I can see to fix this would
1148 * be to convert the inherited-column info to
1149 * ColumnDef nodes before we reach this point,
1150 * and then create the table from those nodes
1151 * rather than referencing the parent tables
1152 * later. That would likely be cleaner, but
1153 * too much work to contemplate right now.
1154 * Instead, raise an error if the inherited
1155 * column won't be NOT NULL. (Would a WARNING
1156 * be more reasonable?)
1158 if (constraint->contype == CONSTR_PRIMARY &&
1159 !inhattr->attnotnull)
1160 elog(ERROR, "inherited attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL",
1165 heap_close(rel, NoLock);
1170 else if (OidIsValid(cxt->relOid))
1172 /* ALTER TABLE case: does column already exist? */
1175 atttuple = SearchSysCache(ATTNAME,
1176 ObjectIdGetDatum(cxt->relOid),
1177 PointerGetDatum(key->name),
1179 if (HeapTupleIsValid(atttuple))
1184 * We require pre-existing column to be already marked
1187 if (constraint->contype == CONSTR_PRIMARY &&
1188 !((Form_pg_attribute) GETSTRUCT(atttuple))->attnotnull)
1189 elog(ERROR, "Existing attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL",
1191 ReleaseSysCache(atttuple);
1196 elog(ERROR, "%s: column \"%s\" named in key does not exist",
1197 cxt->stmtType, key->name);
1199 /* Check for PRIMARY KEY(foo, foo) */
1200 foreach(columns, index->indexParams)
1202 iparam = (IndexElem *) lfirst(columns);
1203 if (iparam->name && strcmp(key->name, iparam->name) == 0)
1204 elog(ERROR, "%s: column \"%s\" appears twice in %s constraint",
1205 cxt->stmtType, key->name,
1206 index->primary ? "PRIMARY KEY" : "UNIQUE");
1209 /* OK, add it to the index definition */
1210 iparam = makeNode(IndexElem);
1211 iparam->name = pstrdup(key->name);
1212 iparam->funcname = NIL;
1214 iparam->opclass = NIL;
1215 index->indexParams = lappend(index->indexParams, iparam);
1218 indexlist = lappend(indexlist, index);
1222 * Scan the index list and remove any redundant index specifications.
1223 * This can happen if, for instance, the user writes SERIAL PRIMARY
1224 * KEY or SERIAL UNIQUE. A strict reading of SQL92 would suggest
1225 * raising an error instead, but that strikes me as too
1226 * anal-retentive. - tgl 2001-02-14
1228 * XXX in ALTER TABLE case, it'd be nice to look for duplicate
1229 * pre-existing indexes, too.
1232 if (cxt->pkey != NULL)
1234 /* Make sure we keep the PKEY index in preference to others... */
1235 cxt->alist = makeList1(cxt->pkey);
1237 while (indexlist != NIL)
1239 index = lfirst(indexlist);
1241 /* if it's pkey, it's already in cxt->alist */
1242 if (index != cxt->pkey)
1247 foreach(priorlist, cxt->alist)
1249 IndexStmt *priorindex = lfirst(priorlist);
1251 if (equal(index->indexParams, priorindex->indexParams))
1254 * If the prior index is as yet unnamed, and this one
1255 * is named, then transfer the name to the prior
1256 * index. This ensures that if we have named and
1257 * unnamed constraints, we'll use (at least one of)
1258 * the names for the index.
1260 if (priorindex->idxname == NULL)
1261 priorindex->idxname = index->idxname;
1268 cxt->alist = lappend(cxt->alist, index);
1271 indexlist = lnext(indexlist);
1275 * Finally, select unique names for all not-previously-named indices,
1276 * and display WARNING messages.
1278 * XXX in ALTER TABLE case, we fail to consider name collisions against
1279 * pre-existing indexes.
1281 foreach(indexlist, cxt->alist)
1283 index = lfirst(indexlist);
1285 if (index->idxname == NULL && index->indexParams != NIL)
1287 iparam = lfirst(index->indexParams);
1288 index->idxname = CreateIndexName(cxt->relation->relname,
1289 iparam->name ? iparam->name :
1290 strVal(llast(iparam->funcname)),
1293 if (index->idxname == NULL) /* should not happen */
1294 elog(ERROR, "%s: failed to make implicit index name",
1297 elog(NOTICE, "%s / %s%s will create implicit index '%s' for table '%s'",
1299 (strcmp(cxt->stmtType, "ALTER TABLE") == 0) ? "ADD " : "",
1300 (index->primary ? "PRIMARY KEY" : "UNIQUE"),
1301 index->idxname, cxt->relation->relname);
1306 transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt)
1308 List *fkactions = NIL;
1311 if (cxt->fkconstraints == NIL)
1314 elog(NOTICE, "%s will create implicit trigger(s) for FOREIGN KEY check(s)",
1317 foreach(fkclist, cxt->fkconstraints)
1319 FkConstraint *fkconstraint = (FkConstraint *) lfirst(fkclist);
1320 Oid pktypoid[INDEX_MAX_KEYS];
1321 Oid fktypoid[INDEX_MAX_KEYS];
1326 for (attnum = 0; attnum < INDEX_MAX_KEYS; attnum++)
1327 pktypoid[attnum] = fktypoid[attnum] = InvalidOid;
1330 * Look up the referencing attributes to make sure they exist (or
1331 * will exist) in this table, and remember their type OIDs.
1334 foreach(fkattrs, fkconstraint->fk_attrs)
1336 Ident *fkattr = lfirst(fkattrs);
1338 if (attnum >= INDEX_MAX_KEYS)
1339 elog(ERROR, "Can only have %d keys in a foreign key",
1341 fktypoid[attnum++] = transformFkeyGetColType(cxt,
1346 * If the attribute list for the referenced table was omitted,
1347 * lookup the definition of the primary key.
1349 if (fkconstraint->pk_attrs == NIL)
1351 if (strcmp(fkconstraint->pktable->relname, (cxt->relation)->relname) != 0)
1352 transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
1353 else if (cxt->pkey != NULL)
1355 /* Use the to-be-created primary key */
1359 foreach(attr, cxt->pkey->indexParams)
1361 IndexElem *ielem = lfirst(attr);
1362 Ident *pkattr = (Ident *) makeNode(Ident);
1364 Assert(ielem->name); /* no func index here */
1365 pkattr->name = pstrdup(ielem->name);
1366 fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs,
1368 if (attnum >= INDEX_MAX_KEYS)
1369 elog(ERROR, "Can only have %d keys in a foreign key",
1371 pktypoid[attnum++] = transformFkeyGetColType(cxt,
1377 /* In ALTER TABLE case, primary key may already exist */
1378 if (OidIsValid(cxt->relOid))
1379 transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
1381 elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
1382 fkconstraint->pktable->relname);
1387 /* Validate the specified referenced key list */
1388 if (strcmp(fkconstraint->pktable->relname, (cxt->relation)->relname) != 0)
1389 transformFkeyCheckAttrs(fkconstraint, pktypoid);
1392 /* Look for a matching new unique/primary constraint */
1396 foreach(index, cxt->alist)
1398 IndexStmt *ind = lfirst(index);
1403 if (length(ind->indexParams) !=
1404 length(fkconstraint->pk_attrs))
1407 foreach(pkattrs, fkconstraint->pk_attrs)
1409 Ident *pkattr = lfirst(pkattrs);
1413 foreach(indparms, ind->indexParams)
1415 IndexElem *indparm = lfirst(indparms);
1417 if (indparm->name &&
1418 strcmp(indparm->name, pkattr->name) == 0)
1426 if (attnum >= INDEX_MAX_KEYS)
1427 elog(ERROR, "Can only have %d keys in a foreign key",
1429 pktypoid[attnum++] = transformFkeyGetColType(cxt,
1438 * In ALTER TABLE case, such an index may already
1441 if (OidIsValid(cxt->relOid))
1442 transformFkeyCheckAttrs(fkconstraint, pktypoid);
1444 elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
1445 fkconstraint->pktable->relname);
1450 /* Be sure referencing and referenced column types are comparable */
1451 for (i = 0; i < INDEX_MAX_KEYS && fktypoid[i] != 0; i++)
1454 * fktypoid[i] is the foreign key table's i'th element's type
1455 * pktypoid[i] is the primary key table's i'th element's type
1457 * We let oper() do our work for us, including elog(ERROR) if
1458 * the types don't compare with =
1460 Operator o = oper(makeList1(makeString("=")),
1461 fktypoid[i], pktypoid[i], false);
1467 * For ALTER TABLE ADD CONSTRAINT, we're done. For CREATE TABLE,
1468 * gin up an ALTER TABLE ADD CONSTRAINT command to execute after
1469 * the basic CREATE TABLE is complete.
1471 if (strcmp(cxt->stmtType, "CREATE TABLE") == 0)
1473 AlterTableStmt *alterstmt = makeNode(AlterTableStmt);
1475 alterstmt->subtype = 'c'; /* preprocessed add constraint */
1476 alterstmt->relation = cxt->relation;
1477 alterstmt->name = NULL;
1478 alterstmt->def = (Node *) makeList1(fkconstraint);
1480 /* Don't need to scan the table contents in this case */
1481 fkconstraint->skip_validation = true;
1483 fkactions = lappend(fkactions, (Node *) alterstmt);
1488 * Attach completed list of extra actions to cxt->alist. We cannot do
1489 * this earlier, because we assume above that cxt->alist still holds
1492 cxt->alist = nconc(cxt->alist, fkactions);
1496 * transformIndexStmt -
1497 * transforms the qualification of the index statement
1500 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
1505 qry = makeNode(Query);
1506 qry->commandType = CMD_UTILITY;
1508 /* take care of the where clause */
1509 if (stmt->whereClause)
1512 * Put the parent table into the rtable so that the WHERE clause
1513 * can refer to its fields without qualification. Note that this
1514 * only works if the parent table already exists --- so we can't
1515 * easily support predicates on indexes created implicitly by
1516 * CREATE TABLE. Fortunately, that's not necessary.
1518 rte = addRangeTableEntry(pstate, stmt->relation, NULL, false, true);
1520 /* no to join list, yes to namespace */
1521 addRTEtoQuery(pstate, rte, false, true);
1523 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1526 qry->hasSubLinks = pstate->p_hasSubLinks;
1527 stmt->rangetable = pstate->p_rtable;
1529 qry->utilityStmt = (Node *) stmt;
1535 * transformRuleStmt -
1536 * transform a Create Rule Statement. The actions is a list of parse
1537 * trees which is transformed into a list of query trees.
1540 transformRuleStmt(ParseState *pstate, RuleStmt *stmt,
1541 List **extras_before, List **extras_after)
1544 RangeTblEntry *oldrte;
1545 RangeTblEntry *newrte;
1547 qry = makeNode(Query);
1548 qry->commandType = CMD_UTILITY;
1549 qry->utilityStmt = (Node *) stmt;
1552 * To avoid deadlock, make sure the first thing we do is grab
1553 * AccessExclusiveLock on the target relation. This will be needed by
1554 * DefineQueryRewrite(), and we don't want to grab a lesser lock
1555 * beforehand. We don't need to hold a refcount on the relcache
1558 heap_close(heap_openrv(stmt->relation, AccessExclusiveLock),
1562 * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to
1563 * 2. Set up their RTEs in the main pstate for use in parsing the
1564 * rule qualification.
1566 Assert(pstate->p_rtable == NIL);
1567 oldrte = addRangeTableEntry(pstate, stmt->relation,
1568 makeAlias("*OLD*", NIL),
1570 newrte = addRangeTableEntry(pstate, stmt->relation,
1571 makeAlias("*NEW*", NIL),
1573 /* Must override addRangeTableEntry's default access-check flags */
1574 oldrte->checkForRead = false;
1575 newrte->checkForRead = false;
1578 * They must be in the namespace too for lookup purposes, but only add
1579 * the one(s) that are relevant for the current kind of rule. In an
1580 * UPDATE rule, quals must refer to OLD.field or NEW.field to be
1581 * unambiguous, but there's no need to be so picky for INSERT &
1582 * DELETE. (Note we marked the RTEs "inFromCl = true" above to allow
1583 * unqualified references to their fields.) We do not add them to the
1586 switch (stmt->event)
1589 addRTEtoQuery(pstate, oldrte, false, true);
1592 addRTEtoQuery(pstate, oldrte, false, true);
1593 addRTEtoQuery(pstate, newrte, false, true);
1596 addRTEtoQuery(pstate, newrte, false, true);
1599 addRTEtoQuery(pstate, oldrte, false, true);
1602 elog(ERROR, "transformRuleStmt: unexpected event type %d",
1607 /* take care of the where clause */
1608 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1610 if (length(pstate->p_rtable) != 2) /* naughty, naughty... */
1611 elog(ERROR, "Rule WHERE condition may not contain references to other relations");
1613 /* save info about sublinks in where clause */
1614 qry->hasSubLinks = pstate->p_hasSubLinks;
1617 * 'instead nothing' rules with a qualification need a query
1618 * rangetable so the rewrite handler can add the negated rule
1619 * qualification to the original query. We create a query with the new
1620 * command type CMD_NOTHING here that is treated specially by the
1623 if (stmt->actions == NIL)
1625 Query *nothing_qry = makeNode(Query);
1627 nothing_qry->commandType = CMD_NOTHING;
1628 nothing_qry->rtable = pstate->p_rtable;
1629 nothing_qry->jointree = makeFromExpr(NIL, NULL); /* no join wanted */
1631 stmt->actions = makeList1(nothing_qry);
1636 List *newactions = NIL;
1639 * transform each statement, like parse_analyze()
1641 foreach(oldactions, stmt->actions)
1643 Node *action = (Node *) lfirst(oldactions);
1644 ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
1651 * Set up OLD/NEW in the rtable for this statement. The
1652 * entries are marked not inFromCl because we don't want them
1653 * to be referred to by unqualified field names nor "*" in the
1654 * rule actions. We must add them to the namespace, however,
1655 * or they won't be accessible at all. We decide later
1656 * whether to put them in the joinlist.
1658 oldrte = addRangeTableEntry(sub_pstate, stmt->relation,
1659 makeAlias("*OLD*", NIL),
1661 newrte = addRangeTableEntry(sub_pstate, stmt->relation,
1662 makeAlias("*NEW*", NIL),
1664 oldrte->checkForRead = false;
1665 newrte->checkForRead = false;
1666 addRTEtoQuery(sub_pstate, oldrte, false, true);
1667 addRTEtoQuery(sub_pstate, newrte, false, true);
1669 /* Transform the rule action statement */
1670 top_subqry = transformStmt(sub_pstate, action,
1671 extras_before, extras_after);
1674 * We cannot support utility-statement actions (eg NOTIFY)
1675 * with nonempty rule WHERE conditions, because there's no way
1676 * to make the utility action execute conditionally.
1678 if (top_subqry->commandType == CMD_UTILITY &&
1679 stmt->whereClause != NULL)
1680 elog(ERROR, "Rules with WHERE conditions may only have SELECT, INSERT, UPDATE, or DELETE actions");
1683 * If the action is INSERT...SELECT, OLD/NEW have been pushed
1684 * down into the SELECT, and that's what we need to look at.
1685 * (Ugly kluge ... try to fix this when we redesign
1688 sub_qry = getInsertSelectQuery(top_subqry, NULL);
1691 * Validate action's use of OLD/NEW, qual too
1694 rangeTableEntry_used((Node *) sub_qry, PRS2_OLD_VARNO, 0) ||
1695 rangeTableEntry_used(stmt->whereClause, PRS2_OLD_VARNO, 0);
1697 rangeTableEntry_used((Node *) sub_qry, PRS2_NEW_VARNO, 0) ||
1698 rangeTableEntry_used(stmt->whereClause, PRS2_NEW_VARNO, 0);
1700 switch (stmt->event)
1704 elog(ERROR, "ON SELECT rule may not use OLD");
1706 elog(ERROR, "ON SELECT rule may not use NEW");
1713 elog(ERROR, "ON INSERT rule may not use OLD");
1717 elog(ERROR, "ON DELETE rule may not use NEW");
1720 elog(ERROR, "transformRuleStmt: unexpected event type %d",
1726 * For efficiency's sake, add OLD to the rule action's
1727 * jointree only if it was actually referenced in the
1728 * statement or qual.
1730 * For INSERT, NEW is not really a relation (only a reference to
1731 * the to-be-inserted tuple) and should never be added to the
1734 * For UPDATE, we treat NEW as being another kind of reference to
1735 * OLD, because it represents references to *transformed*
1736 * tuples of the existing relation. It would be wrong to
1737 * enter NEW separately in the jointree, since that would
1738 * cause a double join of the updated relation. It's also
1739 * wrong to fail to make a jointree entry if only NEW and not
1742 if (has_old || (has_new && stmt->event == CMD_UPDATE))
1744 /* hack so we can use addRTEtoQuery() */
1745 sub_pstate->p_rtable = sub_qry->rtable;
1746 sub_pstate->p_joinlist = sub_qry->jointree->fromlist;
1747 addRTEtoQuery(sub_pstate, oldrte, true, false);
1748 sub_qry->jointree->fromlist = sub_pstate->p_joinlist;
1751 newactions = lappend(newactions, top_subqry);
1753 release_pstate_resources(sub_pstate);
1757 stmt->actions = newactions;
1765 * transformSelectStmt -
1766 * transforms a Select Statement
1768 * Note: this is also used for DECLARE CURSOR statements.
1771 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
1773 Query *qry = makeNode(Query);
1776 qry->commandType = CMD_SELECT;
1778 if (stmt->portalname)
1780 /* DECLARE CURSOR */
1782 elog(ERROR, "DECLARE CURSOR must not specify INTO");
1783 if (stmt->forUpdate)
1784 elog(ERROR, "DECLARE/UPDATE is not supported"
1785 "\n\tCursors must be READ ONLY");
1788 * 15 august 1991 -- since 3.0 postgres does locking right, we
1789 * discovered that portals were violating locking protocol. portal
1790 * locks cannot span xacts. as a short-term fix, we installed the
1791 * check here. -- mao
1793 if (!IsTransactionBlock())
1794 elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
1796 qry->into = makeNode(RangeVar);
1797 qry->into->relname = stmt->portalname;
1798 qry->isPortal = TRUE;
1799 qry->isBinary = stmt->binary; /* internal portal */
1804 qry->into = stmt->into;
1805 qry->isPortal = FALSE;
1806 qry->isBinary = FALSE;
1809 /* make FOR UPDATE clause available to addRangeTableEntry */
1810 pstate->p_forUpdate = stmt->forUpdate;
1812 /* process the FROM clause */
1813 transformFromClause(pstate, stmt->fromClause);
1815 /* transform targetlist */
1816 qry->targetList = transformTargetList(pstate, stmt->targetList);
1818 if (stmt->intoColNames)
1819 applyColumnNames(qry->targetList, stmt->intoColNames);
1821 /* transform WHERE */
1822 qual = transformWhereClause(pstate, stmt->whereClause);
1825 * Initial processing of HAVING clause is just like WHERE clause.
1826 * Additional work will be done in optimizer/plan/planner.c.
1828 qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
1830 qry->groupClause = transformGroupClause(pstate,
1834 qry->sortClause = transformSortClause(pstate,
1838 qry->distinctClause = transformDistinctClause(pstate,
1839 stmt->distinctClause,
1843 qry->limitOffset = stmt->limitOffset;
1844 qry->limitCount = stmt->limitCount;
1846 qry->hasSubLinks = pstate->p_hasSubLinks;
1847 qry->hasAggs = pstate->p_hasAggs;
1848 if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
1849 parseCheckAggregates(pstate, qry, qual);
1851 qry->rtable = pstate->p_rtable;
1852 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
1854 if (stmt->forUpdate != NIL)
1855 transformForUpdate(qry, stmt->forUpdate);
1861 * transformSetOperationsStmt -
1862 * transforms a set-operations tree
1864 * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT
1865 * structure to it. We must transform each leaf SELECT and build up a top-
1866 * level Query that contains the leaf SELECTs as subqueries in its rangetable.
1867 * The tree of set operations is converted into the setOperations field of
1868 * the top-level Query.
1871 transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
1873 Query *qry = makeNode(Query);
1874 SelectStmt *leftmostSelect;
1876 Query *leftmostQuery;
1877 SetOperationStmt *sostmt;
1893 RangeTblEntry *jrte;
1897 qry->commandType = CMD_SELECT;
1900 * Find leftmost leaf SelectStmt; extract the one-time-only items from
1901 * it and from the top-level node.
1903 leftmostSelect = stmt->larg;
1904 while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
1905 leftmostSelect = leftmostSelect->larg;
1906 Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
1907 leftmostSelect->larg == NULL);
1908 into = leftmostSelect->into;
1909 intoColNames = leftmostSelect->intoColNames;
1910 portalname = stmt->portalname;
1911 binary = stmt->binary;
1913 /* clear them to prevent complaints in transformSetOperationTree() */
1914 leftmostSelect->into = NULL;
1915 leftmostSelect->intoColNames = NIL;
1916 stmt->portalname = NULL;
1917 stmt->binary = false;
1920 * These are not one-time, exactly, but we want to process them here
1921 * and not let transformSetOperationTree() see them --- else it'll
1922 * just recurse right back here!
1924 sortClause = stmt->sortClause;
1925 limitOffset = stmt->limitOffset;
1926 limitCount = stmt->limitCount;
1927 forUpdate = stmt->forUpdate;
1929 stmt->sortClause = NIL;
1930 stmt->limitOffset = NULL;
1931 stmt->limitCount = NULL;
1932 stmt->forUpdate = NIL;
1934 /* We don't support forUpdate with set ops at the moment. */
1936 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
1939 * Recursively transform the components of the tree.
1941 sostmt = (SetOperationStmt *) transformSetOperationTree(pstate, stmt);
1942 Assert(sostmt && IsA(sostmt, SetOperationStmt));
1943 qry->setOperations = (Node *) sostmt;
1946 * Re-find leftmost SELECT (now it's a sub-query in rangetable)
1948 node = sostmt->larg;
1949 while (node && IsA(node, SetOperationStmt))
1950 node = ((SetOperationStmt *) node)->larg;
1951 Assert(node && IsA(node, RangeTblRef));
1952 leftmostRTI = ((RangeTblRef *) node)->rtindex;
1953 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
1954 Assert(leftmostQuery != NULL);
1957 * Generate dummy targetlist for outer query using column names of
1958 * leftmost select and common datatypes of topmost set operation. Also
1959 * make lists of the dummy vars and their names for use in parsing
1962 qry->targetList = NIL;
1965 lefttl = leftmostQuery->targetList;
1966 foreach(dtlist, sostmt->colTypes)
1968 Oid colType = (Oid) lfirsti(dtlist);
1969 Resdom *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
1970 char *colName = pstrdup(leftResdom->resname);
1974 resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
1979 expr = (Node *) makeVar(1,
1984 qry->targetList = lappend(qry->targetList,
1985 makeTargetEntry(resdom, expr));
1986 targetvars = lappend(targetvars, expr);
1987 targetnames = lappend(targetnames, makeString(colName));
1988 lefttl = lnext(lefttl);
1992 * Insert one-time items into top-level query
1994 * This needs to agree with transformSelectStmt!
1998 /* DECLARE CURSOR */
2000 elog(ERROR, "DECLARE CURSOR must not specify INTO");
2002 elog(ERROR, "DECLARE/UPDATE is not supported"
2003 "\n\tCursors must be READ ONLY");
2006 * 15 august 1991 -- since 3.0 postgres does locking right, we
2007 * discovered that portals were violating locking protocol. portal
2008 * locks cannot span xacts. as a short-term fix, we installed the
2009 * check here. -- mao
2011 if (!IsTransactionBlock())
2012 elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
2014 qry->into = makeNode(RangeVar);
2015 qry->into->relname = portalname;
2016 qry->isPortal = TRUE;
2017 qry->isBinary = binary; /* internal portal */
2023 qry->isPortal = FALSE;
2024 qry->isBinary = FALSE;
2028 * Any column names from CREATE TABLE AS need to be attached to both the
2029 * top level and the leftmost subquery. We do not do this earlier
2030 * because we do *not* want the targetnames list to be affected.
2034 applyColumnNames(qry->targetList, intoColNames);
2035 applyColumnNames(leftmostQuery->targetList, intoColNames);
2039 * As a first step towards supporting sort clauses that are
2040 * expressions using the output columns, generate a namespace entry
2041 * that makes the output columns visible. A Join RTE node is handy
2042 * for this, since we can easily control the Vars generated upon
2045 * Note: we don't yet do anything useful with such cases, but at least
2046 * "ORDER BY upper(foo)" will draw the right error message rather than
2049 jrte = addRangeTableEntryForJoin(NULL,
2055 jrtr = makeNode(RangeTblRef);
2058 sv_rtable = pstate->p_rtable;
2059 pstate->p_rtable = makeList1(jrte);
2061 sv_namespace = pstate->p_namespace;
2062 pstate->p_namespace = makeList1(jrtr);
2065 * For now, we don't support resjunk sort clauses on the output of a
2066 * setOperation tree --- you can only use the SQL92-spec options of
2067 * selecting an output column by name or number. Enforce by checking
2068 * that transformSortClause doesn't add any items to tlist.
2070 tllen = length(qry->targetList);
2072 qry->sortClause = transformSortClause(pstate,
2076 pstate->p_namespace = sv_namespace;
2077 pstate->p_rtable = sv_rtable;
2079 if (tllen != length(qry->targetList))
2080 elog(ERROR, "ORDER BY on a UNION/INTERSECT/EXCEPT result must be on one of the result columns");
2082 qry->limitOffset = limitOffset;
2083 qry->limitCount = limitCount;
2085 qry->hasSubLinks = pstate->p_hasSubLinks;
2086 qry->hasAggs = pstate->p_hasAggs;
2087 if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
2088 parseCheckAggregates(pstate, qry, NULL);
2090 qry->rtable = pstate->p_rtable;
2091 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
2093 if (forUpdate != NIL)
2094 transformForUpdate(qry, forUpdate);
2100 * transformSetOperationTree
2101 * Recursively transform leaves and internal nodes of a set-op tree
2104 transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
2108 Assert(stmt && IsA(stmt, SelectStmt));
2111 * Validity-check both leaf and internal SELECTs for disallowed ops.
2114 elog(ERROR, "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT");
2115 if (stmt->portalname) /* should not happen */
2116 elog(ERROR, "Portal may not appear in UNION/INTERSECT/EXCEPT");
2117 /* We don't support forUpdate with set ops at the moment. */
2118 if (stmt->forUpdate)
2119 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2122 * If an internal node of a set-op tree has ORDER BY, UPDATE, or LIMIT
2123 * clauses attached, we need to treat it like a leaf node to generate
2124 * an independent sub-Query tree. Otherwise, it can be represented by
2125 * a SetOperationStmt node underneath the parent Query.
2127 if (stmt->op == SETOP_NONE)
2129 Assert(stmt->larg == NULL && stmt->rarg == NULL);
2134 Assert(stmt->larg != NULL && stmt->rarg != NULL);
2135 if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
2144 /* Process leaf SELECT */
2147 char selectName[32];
2152 * Transform SelectStmt into a Query.
2154 * Note: previously transformed sub-queries don't affect the parsing
2155 * of this sub-query, because they are not in the toplevel
2156 * pstate's namespace list.
2158 selectList = parse_analyze((Node *) stmt, pstate);
2160 Assert(length(selectList) == 1);
2161 selectQuery = (Query *) lfirst(selectList);
2164 * Make the leaf query be a subquery in the top-level rangetable.
2166 sprintf(selectName, "*SELECT* %d", length(pstate->p_rtable) + 1);
2167 rte = addRangeTableEntryForSubquery(pstate,
2169 makeAlias(selectName, NIL),
2173 * Return a RangeTblRef to replace the SelectStmt in the set-op
2176 rtr = makeNode(RangeTblRef);
2177 /* assume new rte is at end */
2178 rtr->rtindex = length(pstate->p_rtable);
2179 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
2180 return (Node *) rtr;
2184 /* Process an internal node (set operation node) */
2185 SetOperationStmt *op = makeNode(SetOperationStmt);
2188 const char *context;
2190 context = (stmt->op == SETOP_UNION ? "UNION" :
2191 (stmt->op == SETOP_INTERSECT ? "INTERSECT" :
2195 op->all = stmt->all;
2198 * Recursively transform the child nodes.
2200 op->larg = transformSetOperationTree(pstate, stmt->larg);
2201 op->rarg = transformSetOperationTree(pstate, stmt->rarg);
2204 * Verify that the two children have the same number of non-junk
2205 * columns, and determine the types of the merged output columns.
2207 lcoltypes = getSetColTypes(pstate, op->larg);
2208 rcoltypes = getSetColTypes(pstate, op->rarg);
2209 if (length(lcoltypes) != length(rcoltypes))
2210 elog(ERROR, "Each %s query must have the same number of columns",
2213 while (lcoltypes != NIL)
2215 Oid lcoltype = (Oid) lfirsti(lcoltypes);
2216 Oid rcoltype = (Oid) lfirsti(rcoltypes);
2219 rescoltype = select_common_type(makeListi2(lcoltype, rcoltype),
2221 op->colTypes = lappendi(op->colTypes, rescoltype);
2222 lcoltypes = lnext(lcoltypes);
2223 rcoltypes = lnext(rcoltypes);
2232 * Get output column types of an (already transformed) set-op node
2235 getSetColTypes(ParseState *pstate, Node *node)
2237 if (IsA(node, RangeTblRef))
2239 RangeTblRef *rtr = (RangeTblRef *) node;
2240 RangeTblEntry *rte = rt_fetch(rtr->rtindex, pstate->p_rtable);
2241 Query *selectQuery = rte->subquery;
2245 Assert(selectQuery != NULL);
2246 /* Get types of non-junk columns */
2247 foreach(tl, selectQuery->targetList)
2249 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2250 Resdom *resnode = tle->resdom;
2252 if (resnode->resjunk)
2254 result = lappendi(result, resnode->restype);
2258 else if (IsA(node, SetOperationStmt))
2260 SetOperationStmt *op = (SetOperationStmt *) node;
2262 /* Result already computed during transformation of node */
2263 Assert(op->colTypes != NIL);
2264 return op->colTypes;
2268 elog(ERROR, "getSetColTypes: unexpected node %d",
2269 (int) nodeTag(node));
2270 return NIL; /* keep compiler quiet */
2274 /* Attach column names from a ColumnDef list to a TargetEntry list */
2276 applyColumnNames(List *dst, List *src)
2278 if (length(src) > length(dst))
2279 elog(ERROR, "CREATE TABLE AS specifies too many column names");
2281 while (src != NIL && dst != NIL)
2283 TargetEntry *d = (TargetEntry *) lfirst(dst);
2284 ColumnDef *s = (ColumnDef *) lfirst(src);
2286 Assert(d->resdom && !d->resdom->resjunk);
2288 d->resdom->resname = pstrdup(s->colname);
2297 * transformUpdateStmt -
2298 * transforms an update statement
2301 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
2303 Query *qry = makeNode(Query);
2305 List *origTargetList;
2308 qry->commandType = CMD_UPDATE;
2309 pstate->p_is_update = true;
2311 qry->resultRelation = setTargetTable(pstate, stmt->relation,
2312 interpretInhOption(stmt->relation->inhOpt),
2316 * the FROM clause is non-standard SQL syntax. We used to be able to
2317 * do this with REPLACE in POSTQUEL so we keep the feature.
2319 transformFromClause(pstate, stmt->fromClause);
2321 qry->targetList = transformTargetList(pstate, stmt->targetList);
2323 qual = transformWhereClause(pstate, stmt->whereClause);
2325 qry->rtable = pstate->p_rtable;
2326 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
2328 qry->hasSubLinks = pstate->p_hasSubLinks;
2329 qry->hasAggs = pstate->p_hasAggs;
2330 if (pstate->p_hasAggs)
2331 parseCheckAggregates(pstate, qry, qual);
2334 * Now we are done with SELECT-like processing, and can get on with
2335 * transforming the target list to match the UPDATE target columns.
2338 /* Prepare to assign non-conflicting resnos to resjunk attributes */
2339 if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
2340 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
2342 /* Prepare non-junk columns for assignment to target table */
2343 origTargetList = stmt->targetList;
2344 foreach(tl, qry->targetList)
2346 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2347 Resdom *resnode = tle->resdom;
2348 ResTarget *origTarget;
2350 if (resnode->resjunk)
2353 * Resjunk nodes need no additional processing, but be sure
2354 * they have names and resnos that do not match any target
2355 * columns; else rewriter or planner might get confused.
2357 resnode->resname = "?resjunk?";
2358 resnode->resno = (AttrNumber) pstate->p_last_resno++;
2361 if (origTargetList == NIL)
2362 elog(ERROR, "UPDATE target count mismatch --- internal error");
2363 origTarget = (ResTarget *) lfirst(origTargetList);
2364 updateTargetListEntry(pstate, tle, origTarget->name,
2365 attnameAttNum(pstate->p_target_relation,
2367 origTarget->indirection);
2368 origTargetList = lnext(origTargetList);
2370 if (origTargetList != NIL)
2371 elog(ERROR, "UPDATE target count mismatch --- internal error");
2377 * tranformAlterTableStmt -
2378 * transform an Alter Table Statement
2381 transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt,
2382 List **extras_before, List **extras_after)
2384 CreateStmtContext cxt;
2388 * The only subtypes that currently require parse transformation
2389 * handling are 'A'dd column and Add 'C'onstraint. These largely
2390 * re-use code from CREATE TABLE.
2392 switch (stmt->subtype)
2395 cxt.stmtType = "ALTER TABLE";
2396 cxt.relation = stmt->relation;
2397 cxt.inhRelations = NIL;
2398 cxt.relOid = RangeVarGetRelid(stmt->relation, false);
2399 cxt.hasoids = SearchSysCacheExists(ATTNUM,
2400 ObjectIdGetDatum(cxt.relOid),
2401 Int16GetDatum(ObjectIdAttributeNumber),
2404 cxt.ckconstraints = NIL;
2405 cxt.fkconstraints = NIL;
2406 cxt.ixconstraints = NIL;
2411 Assert(IsA(stmt->def, ColumnDef));
2412 transformColumnDefinition(pstate, &cxt,
2413 (ColumnDef *) stmt->def);
2415 transformIndexConstraints(pstate, &cxt);
2416 transformFKConstraints(pstate, &cxt);
2418 ((ColumnDef *) stmt->def)->constraints = cxt.ckconstraints;
2419 *extras_before = nconc(*extras_before, cxt.blist);
2420 *extras_after = nconc(cxt.alist, *extras_after);
2424 cxt.stmtType = "ALTER TABLE";
2425 cxt.relation = stmt->relation;
2426 cxt.inhRelations = NIL;
2427 cxt.relOid = RangeVarGetRelid(stmt->relation, false);
2428 cxt.hasoids = SearchSysCacheExists(ATTNUM,
2429 ObjectIdGetDatum(cxt.relOid),
2430 Int16GetDatum(ObjectIdAttributeNumber),
2433 cxt.ckconstraints = NIL;
2434 cxt.fkconstraints = NIL;
2435 cxt.ixconstraints = NIL;
2440 if (IsA(stmt->def, Constraint))
2441 transformTableConstraint(pstate, &cxt,
2442 (Constraint *) stmt->def);
2443 else if (IsA(stmt->def, FkConstraint))
2444 cxt.fkconstraints = lappend(cxt.fkconstraints, stmt->def);
2446 elog(ERROR, "Unexpected node type in ALTER TABLE ADD CONSTRAINT");
2448 transformIndexConstraints(pstate, &cxt);
2449 transformFKConstraints(pstate, &cxt);
2451 Assert(cxt.columns == NIL);
2452 stmt->def = (Node *) nconc(cxt.ckconstraints, cxt.fkconstraints);
2453 *extras_before = nconc(*extras_before, cxt.blist);
2454 *extras_after = nconc(cxt.alist, *extras_after);
2459 * Already-transformed ADD CONSTRAINT, so just make it look
2460 * like the standard case.
2462 stmt->subtype = 'C';
2469 qry = makeNode(Query);
2470 qry->commandType = CMD_UTILITY;
2471 qry->utilityStmt = (Node *) stmt;
2476 /* exported so planner can check again after rewriting, query pullup, etc */
2478 CheckSelectForUpdate(Query *qry)
2480 if (qry->setOperations)
2481 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2482 if (qry->distinctClause != NIL)
2483 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
2484 if (qry->groupClause != NIL)
2485 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
2487 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
2491 transformForUpdate(Query *qry, List *forUpdate)
2493 List *rowMarks = qry->rowMarks;
2498 CheckSelectForUpdate(qry);
2500 if (lfirst(forUpdate) == NULL)
2502 /* all tables used in query */
2504 foreach(rt, qry->rtable)
2506 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2509 if (rte->rtekind == RTE_SUBQUERY)
2511 /* FOR UPDATE of subquery is propagated to subquery's rels */
2512 transformForUpdate(rte->subquery, makeList1(NULL));
2516 if (!intMember(i, rowMarks)) /* avoid duplicates */
2517 rowMarks = lappendi(rowMarks, i);
2518 rte->checkForWrite = true;
2524 /* just the named tables */
2525 foreach(l, forUpdate)
2527 char *relname = strVal(lfirst(l));
2530 foreach(rt, qry->rtable)
2532 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2535 if (strcmp(rte->eref->aliasname, relname) == 0)
2537 if (rte->rtekind == RTE_SUBQUERY)
2539 /* propagate to subquery */
2540 transformForUpdate(rte->subquery, makeList1(NULL));
2544 if (!intMember(i, rowMarks)) /* avoid duplicates */
2545 rowMarks = lappendi(rowMarks, i);
2546 rte->checkForWrite = true;
2552 elog(ERROR, "FOR UPDATE: relation \"%s\" not found in FROM clause",
2557 qry->rowMarks = rowMarks;
2562 * transformFkeyCheckAttrs -
2564 * Make sure that the attributes of a referenced table
2565 * belong to a unique (or primary key) constraint.
2568 transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid)
2577 * Open the referenced table
2579 pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock);
2581 if (pkrel->rd_rel->relkind != RELKIND_RELATION)
2582 elog(ERROR, "Referenced relation \"%s\" is not a table",
2583 fkconstraint->pktable->relname);
2586 * Get the list of index OIDs for the table from the relcache, and
2587 * look up each one in the pg_index syscache for each unique one, and
2588 * then compare the attributes we were given to those defined.
2590 indexoidlist = RelationGetIndexList(pkrel);
2592 foreach(indexoidscan, indexoidlist)
2594 Oid indexoid = lfirsti(indexoidscan);
2595 HeapTuple indexTuple;
2596 Form_pg_index indexStruct;
2599 indexTuple = SearchSysCache(INDEXRELID,
2600 ObjectIdGetDatum(indexoid),
2602 if (!HeapTupleIsValid(indexTuple))
2603 elog(ERROR, "transformFkeyCheckAttrs: index %u not found",
2605 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
2607 if (indexStruct->indisunique)
2609 for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2611 if (i == length(fkconstraint->pk_attrs))
2613 /* go through the fkconstraint->pk_attrs list */
2617 foreach(attrl, fkconstraint->pk_attrs)
2619 Ident *attr = lfirst(attrl);
2622 for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2624 int pkattno = indexStruct->indkey[i];
2626 if (namestrcmp(attnumAttName(pkrel, pkattno),
2629 pktypoid[attnum++] = attnumTypeId(pkrel, pkattno);
2639 ReleaseSysCache(indexTuple);
2644 elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
2645 fkconstraint->pktable->relname);
2647 freeList(indexoidlist);
2648 heap_close(pkrel, AccessShareLock);
2653 * transformFkeyGetPrimaryKey -
2655 * Try to find the primary key attributes of a referenced table if
2656 * the column list in the REFERENCES specification was omitted.
2659 transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
2664 HeapTuple indexTuple = NULL;
2665 Form_pg_index indexStruct = NULL;
2670 * Open the referenced table
2672 pkrel = heap_openrv(fkconstraint->pktable, AccessShareLock);
2674 if (pkrel->rd_rel->relkind != RELKIND_RELATION)
2675 elog(ERROR, "Referenced relation \"%s\" is not a table",
2676 fkconstraint->pktable->relname);
2679 * Get the list of index OIDs for the table from the relcache, and
2680 * look up each one in the pg_index syscache until we find one marked
2681 * primary key (hopefully there isn't more than one such).
2683 indexoidlist = RelationGetIndexList(pkrel);
2685 foreach(indexoidscan, indexoidlist)
2687 Oid indexoid = lfirsti(indexoidscan);
2689 indexTuple = SearchSysCache(INDEXRELID,
2690 ObjectIdGetDatum(indexoid),
2692 if (!HeapTupleIsValid(indexTuple))
2693 elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
2695 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
2696 if (indexStruct->indisprimary)
2698 ReleaseSysCache(indexTuple);
2702 freeList(indexoidlist);
2705 * Check that we found it
2707 if (indexStruct == NULL)
2708 elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
2709 fkconstraint->pktable->relname);
2712 * Now build the list of PK attributes from the indkey definition
2713 * using the attribute names of the PK relation descriptor
2715 for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2717 int pkattno = indexStruct->indkey[i];
2718 Ident *pkattr = makeNode(Ident);
2720 pkattr->name = pstrdup(NameStr(*attnumAttName(pkrel, pkattno)));
2721 pktypoid[attnum++] = attnumTypeId(pkrel, pkattno);
2723 fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
2726 ReleaseSysCache(indexTuple);
2728 heap_close(pkrel, AccessShareLock);
2732 * relationHasPrimaryKey -
2734 * See whether an existing relation has a primary key.
2737 relationHasPrimaryKey(Oid relationOid)
2739 bool result = false;
2744 rel = heap_open(relationOid, AccessShareLock);
2747 * Get the list of index OIDs for the table from the relcache, and
2748 * look up each one in the pg_index syscache until we find one marked
2749 * primary key (hopefully there isn't more than one such).
2751 indexoidlist = RelationGetIndexList(rel);
2753 foreach(indexoidscan, indexoidlist)
2755 Oid indexoid = lfirsti(indexoidscan);
2756 HeapTuple indexTuple;
2758 indexTuple = SearchSysCache(INDEXRELID,
2759 ObjectIdGetDatum(indexoid),
2761 if (!HeapTupleIsValid(indexTuple))
2762 elog(ERROR, "relationHasPrimaryKey: index %u not found",
2764 result = ((Form_pg_index) GETSTRUCT(indexTuple))->indisprimary;
2765 ReleaseSysCache(indexTuple);
2770 freeList(indexoidlist);
2772 heap_close(rel, AccessShareLock);
2778 * transformFkeyGetColType -
2780 * Find a referencing column by name, and return its type OID.
2781 * Error if it can't be found.
2784 transformFkeyGetColType(CreateStmtContext *cxt, char *colname)
2789 Form_pg_attribute sysatt;
2791 /* First look for column among the newly-created columns */
2792 foreach(cols, cxt->columns)
2794 ColumnDef *col = lfirst(cols);
2796 if (strcmp(col->colname, colname) == 0)
2797 return typenameTypeId(col->typename);
2799 /* Perhaps it's a system column name */
2800 sysatt = SystemAttributeByName(colname, cxt->hasoids);
2802 return sysatt->atttypid;
2803 /* Look for column among inherited columns (if CREATE TABLE case) */
2804 foreach(inher, cxt->inhRelations)
2806 RangeVar *inh = lfirst(inher);
2810 Assert(IsA(inh, RangeVar));
2811 rel = heap_openrv(inh, AccessShareLock);
2812 if (rel->rd_rel->relkind != RELKIND_RELATION)
2813 elog(ERROR, "inherited table \"%s\" is not a relation",
2815 for (count = 0; count < rel->rd_att->natts; count++)
2817 char *name = NameStr(rel->rd_att->attrs[count]->attname);
2819 if (strcmp(name, colname) == 0)
2821 result = rel->rd_att->attrs[count]->atttypid;
2822 heap_close(rel, NoLock);
2826 heap_close(rel, NoLock);
2828 /* Look for column among existing columns (if ALTER TABLE case) */
2829 if (OidIsValid(cxt->relOid))
2833 atttuple = SearchSysCache(ATTNAME,
2834 ObjectIdGetDatum(cxt->relOid),
2835 PointerGetDatum(colname),
2837 if (HeapTupleIsValid(atttuple))
2839 result = ((Form_pg_attribute) GETSTRUCT(atttuple))->atttypid;
2840 ReleaseSysCache(atttuple);
2845 elog(ERROR, "%s: column \"%s\" referenced in foreign key constraint does not exist",
2846 cxt->stmtType, colname);
2847 return InvalidOid; /* keep compiler quiet */
2851 * Preprocess a list of column constraint clauses
2852 * to attach constraint attributes to their primary constraint nodes
2853 * and detect inconsistent/misplaced constraint attributes.
2855 * NOTE: currently, attributes are only supported for FOREIGN KEY primary
2856 * constraints, but someday they ought to be supported for other constraints.
2859 transformConstraintAttrs(List *constraintList)
2861 Node *lastprimarynode = NULL;
2862 bool saw_deferrability = false;
2863 bool saw_initially = false;
2866 foreach(clist, constraintList)
2868 Node *node = lfirst(clist);
2870 if (!IsA(node, Constraint))
2872 lastprimarynode = node;
2873 /* reset flags for new primary node */
2874 saw_deferrability = false;
2875 saw_initially = false;
2879 Constraint *con = (Constraint *) node;
2881 switch (con->contype)
2883 case CONSTR_ATTR_DEFERRABLE:
2884 if (lastprimarynode == NULL ||
2885 !IsA(lastprimarynode, FkConstraint))
2886 elog(ERROR, "Misplaced DEFERRABLE clause");
2887 if (saw_deferrability)
2888 elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed");
2889 saw_deferrability = true;
2890 ((FkConstraint *) lastprimarynode)->deferrable = true;
2892 case CONSTR_ATTR_NOT_DEFERRABLE:
2893 if (lastprimarynode == NULL ||
2894 !IsA(lastprimarynode, FkConstraint))
2895 elog(ERROR, "Misplaced NOT DEFERRABLE clause");
2896 if (saw_deferrability)
2897 elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed");
2898 saw_deferrability = true;
2899 ((FkConstraint *) lastprimarynode)->deferrable = false;
2900 if (saw_initially &&
2901 ((FkConstraint *) lastprimarynode)->initdeferred)
2902 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2904 case CONSTR_ATTR_DEFERRED:
2905 if (lastprimarynode == NULL ||
2906 !IsA(lastprimarynode, FkConstraint))
2907 elog(ERROR, "Misplaced INITIALLY DEFERRED clause");
2909 elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed");
2910 saw_initially = true;
2911 ((FkConstraint *) lastprimarynode)->initdeferred = true;
2914 * If only INITIALLY DEFERRED appears, assume
2917 if (!saw_deferrability)
2918 ((FkConstraint *) lastprimarynode)->deferrable = true;
2919 else if (!((FkConstraint *) lastprimarynode)->deferrable)
2920 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2922 case CONSTR_ATTR_IMMEDIATE:
2923 if (lastprimarynode == NULL ||
2924 !IsA(lastprimarynode, FkConstraint))
2925 elog(ERROR, "Misplaced INITIALLY IMMEDIATE clause");
2927 elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed");
2928 saw_initially = true;
2929 ((FkConstraint *) lastprimarynode)->initdeferred = false;
2932 /* Otherwise it's not an attribute */
2933 lastprimarynode = node;
2934 /* reset flags for new primary node */
2935 saw_deferrability = false;
2936 saw_initially = false;
2943 /* Build a FromExpr node */
2945 makeFromExpr(List *fromlist, Node *quals)
2947 FromExpr *f = makeNode(FromExpr);
2949 f->fromlist = fromlist;
2955 * Special handling of type definition for a column
2958 transformColumnType(ParseState *pstate, ColumnDef *column)
2960 TypeName *typename = column->typename;
2961 Type ctype = typenameType(typename);
2964 * Is this the name of a complex type? If so, implement it as a set.
2966 * XXX this is a hangover from ancient Berkeley code that probably
2967 * doesn't work anymore anyway.
2969 if (typeTypeRelid(ctype) != InvalidOid)
2972 * (Eventually add in here that the set can only contain one
2975 typename->setof = true;
2978 ReleaseSysCache(ctype);
2982 * analyzeCreateSchemaStmt -
2983 * analyzes the "create schema" statement
2985 * Split the schema element list into individual commands and place
2986 * them in the result list in an order such that there are no
2987 * forward references (e.g. GRANT to a table created later in the list).
2989 * SQL92 also allows constraints to make forward references, so thumb through
2990 * the table columns and move forward references to a posterior alter-table
2993 * The result is a list of parse nodes that still need to be analyzed ---
2994 * but we can't analyze the later commands until we've executed the earlier
2995 * ones, because of possible inter-object references.
2997 * Note: Called from commands/command.c
3000 analyzeCreateSchemaStmt(CreateSchemaStmt *stmt)
3002 CreateSchemaStmtContext cxt;
3006 cxt.stmtType = "CREATE SCHEMA";
3007 cxt.schemaname = stmt->schemaname;
3008 cxt.authid = stmt->authid;
3012 cxt.fwconstraints = NIL;
3018 * Run through each schema element in the schema element list.
3019 * Separate statements by type, and do preliminary analysis.
3021 foreach(elements, stmt->schemaElts)
3023 Node *element = lfirst(elements);
3025 switch (nodeTag(element))
3029 CreateStmt *elp = (CreateStmt *) element;
3031 if (elp->relation->schemaname == NULL)
3032 elp->relation->schemaname = cxt.schemaname;
3033 else if (strcmp(cxt.schemaname, elp->relation->schemaname) != 0)
3034 elog(ERROR, "New table specifies a schema (%s)"
3035 " different from the one being created (%s)",
3036 elp->relation->schemaname, cxt.schemaname);
3039 * XXX todo: deal with constraints
3042 cxt.tables = lappend(cxt.tables, element);
3048 ViewStmt *elp = (ViewStmt *) element;
3050 if (elp->view->schemaname == NULL)
3051 elp->view->schemaname = cxt.schemaname;
3052 else if (strcmp(cxt.schemaname, elp->view->schemaname) != 0)
3053 elog(ERROR, "New view specifies a schema (%s)"
3054 " different from the one being created (%s)",
3055 elp->view->schemaname, cxt.schemaname);
3058 * XXX todo: deal with references between views
3061 cxt.views = lappend(cxt.views, element);
3066 cxt.grants = lappend(cxt.grants, element);
3070 elog(ERROR, "parser: unsupported schema node (internal error)");
3075 result = nconc(result, cxt.tables);
3076 result = nconc(result, cxt.views);
3077 result = nconc(result, cxt.grants);