1 /*-------------------------------------------------------------------------
4 * transform the parse tree into a query tree
6 * Portions Copyright (c) 1996-2001, 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.189 2001/06/04 23:27:23 momjian Exp $
11 *-------------------------------------------------------------------------
16 #include "access/heapam.h"
17 #include "catalog/catname.h"
18 #include "catalog/pg_index.h"
19 #include "catalog/pg_type.h"
20 #include "nodes/makefuncs.h"
21 #include "parser/analyze.h"
22 #include "parser/parse.h"
23 #include "parser/parsetree.h"
24 #include "parser/parse_agg.h"
25 #include "parser/parse_clause.h"
26 #include "parser/parse_coerce.h"
27 #include "parser/parse_expr.h"
28 #include "parser/parse_oper.h"
29 #include "parser/parse_relation.h"
30 #include "parser/parse_target.h"
31 #include "parser/parse_type.h"
32 #include "parser/parse_expr.h"
33 #include "rewrite/rewriteManip.h"
34 #include "utils/builtins.h"
35 #include "utils/fmgroids.h"
36 #include "utils/relcache.h"
37 #include "utils/syscache.h"
40 #include "mb/pg_wchar.h"
43 static Query *transformStmt(ParseState *pstate, Node *stmt);
44 static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt);
45 static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt);
46 static Query *transformIndexStmt(ParseState *pstate, IndexStmt *stmt);
47 static Query *transformExtendStmt(ParseState *pstate, ExtendStmt *stmt);
48 static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
49 static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt);
50 static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt);
51 static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt);
52 static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt);
53 static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
54 static Query *transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt);
55 static Node *transformTypeRefs(ParseState *pstate, Node *stmt);
57 static void transformTypeRefsList(ParseState *pstate, List *l);
58 static void transformTypeRef(ParseState *pstate, TypeName *tn);
59 static List *getSetColTypes(ParseState *pstate, Node *node);
60 static void transformForUpdate(Query *qry, List *forUpdate);
61 static void transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid);
62 static void transformConstraintAttrs(List *constraintList);
63 static void transformColumnType(ParseState *pstate, ColumnDef *column);
64 static void transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid);
66 static void release_pstate_resources(ParseState *pstate);
67 static FromExpr *makeFromExpr(List *fromlist, Node *quals);
69 /* kluge to return extra info from transformCreateStmt() */
70 static List *extras_before;
71 static List *extras_after;
76 * analyze a raw parse tree and transform it to Query form.
78 * The result is a List of Query nodes (we need a list since some commands
79 * produce multiple Queries). Optimizable statements require considerable
80 * transformation, while many utility-type statements are simply hung off
81 * a dummy CMD_UTILITY Query node.
84 parse_analyze(Node *parseTree, ParseState *parentParseState)
87 ParseState *pstate = make_parsestate(parentParseState);
90 extras_before = extras_after = NIL;
92 query = transformStmt(pstate, parseTree);
93 release_pstate_resources(pstate);
95 while (extras_before != NIL)
97 result = lappend(result,
98 transformStmt(pstate, lfirst(extras_before)));
99 release_pstate_resources(pstate);
100 extras_before = lnext(extras_before);
103 result = lappend(result, query);
105 while (extras_after != NIL)
107 result = lappend(result,
108 transformStmt(pstate, lfirst(extras_after)));
109 release_pstate_resources(pstate);
110 extras_after = lnext(extras_after);
119 release_pstate_resources(ParseState *pstate)
121 if (pstate->p_target_relation != NULL)
122 heap_close(pstate->p_target_relation, NoLock);
123 pstate->p_target_relation = NULL;
124 pstate->p_target_rangetblentry = NULL;
129 * transform a Parse tree into a Query tree.
132 transformStmt(ParseState *pstate, Node *parseTree)
134 Query *result = NULL;
136 switch (nodeTag(parseTree))
140 * Non-optimizable statements
143 result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
147 result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
151 result = transformExtendStmt(pstate, (ExtendStmt *) parseTree);
155 result = transformRuleStmt(pstate, (RuleStmt *) parseTree);
160 ViewStmt *n = (ViewStmt *) parseTree;
162 n->query = transformStmt(pstate, (Node *) n->query);
165 * If a list of column names was given, run through and
166 * insert these into the actual query tree. - thomas
169 if (n->aliases != NIL)
172 List *targetList = n->query->targetList;
174 if (length(targetList) < length(n->aliases))
175 elog(ERROR, "CREATE VIEW specifies %d columns"
176 " but only %d columns are present",
177 length(targetList), length(n->aliases));
179 for (i = 0; i < length(n->aliases); i++)
185 id = nth(i, n->aliases);
186 Assert(IsA(id, Ident));
187 te = nth(i, targetList);
188 Assert(IsA(te, TargetEntry));
190 Assert(IsA(rd, Resdom));
191 rd->resname = pstrdup(id->name);
194 result = makeNode(Query);
195 result->commandType = CMD_UTILITY;
196 result->utilityStmt = (Node *) n;
202 ExplainStmt *n = (ExplainStmt *) parseTree;
204 result = makeNode(Query);
205 result->commandType = CMD_UTILITY;
206 n->query = transformStmt(pstate, (Node *) n->query);
207 result->utilityStmt = (Node *) parseTree;
211 case T_AlterTableStmt:
212 result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree);
216 * Optimizable statements
219 result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
223 result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
227 result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
231 if (((SelectStmt *) parseTree)->op == SETOP_NONE)
232 result = transformSelectStmt(pstate,
233 (SelectStmt *) parseTree);
235 result = transformSetOperationStmt(pstate,
236 (SelectStmt *) parseTree);
240 * Convert use of %TYPE in statements where it is permitted.
242 case T_ProcedureStmt:
244 case T_RemoveFuncStmt:
246 result = makeNode(Query);
247 result->commandType = CMD_UTILITY;
248 result->utilityStmt = transformTypeRefs(pstate, parseTree);
254 * other statements don't require any transformation-- just
255 * return the original parsetree, yea!
257 result = makeNode(Query);
258 result->commandType = CMD_UTILITY;
259 result->utilityStmt = (Node *) parseTree;
266 * transformDeleteStmt -
267 * transforms a Delete Statement
270 transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
272 Query *qry = makeNode(Query);
275 qry->commandType = CMD_DELETE;
277 /* set up range table with just the result rel */
278 qry->resultRelation = setTargetTable(pstate, stmt->relname,
279 interpretInhOption(stmt->inhOpt),
282 qry->distinctClause = NIL;
284 /* fix where clause */
285 qual = transformWhereClause(pstate, stmt->whereClause);
287 /* done building the range table and jointree */
288 qry->rtable = pstate->p_rtable;
289 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
291 qry->hasSubLinks = pstate->p_hasSubLinks;
292 qry->hasAggs = pstate->p_hasAggs;
293 if (pstate->p_hasAggs)
294 parseCheckAggregates(pstate, qry, qual);
300 * transformInsertStmt -
301 * transform an Insert Statement
304 transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
306 Query *qry = makeNode(Query);
316 qry->commandType = CMD_INSERT;
317 pstate->p_is_insert = true;
320 * If a non-nil rangetable/namespace was passed in, and we are doing
321 * INSERT/SELECT, arrange to pass the rangetable/namespace down to the
322 * SELECT. This can only happen if we are inside a CREATE RULE, and
323 * in that case we want the rule's OLD and NEW rtable entries to
324 * appear as part of the SELECT's rtable, not as outer references for
325 * it. (Kluge!) The SELECT's joinlist is not affected however. We
326 * must do this before adding the target table to the INSERT's rtable.
328 if (stmt->selectStmt)
330 sub_rtable = pstate->p_rtable;
331 pstate->p_rtable = NIL;
332 sub_namespace = pstate->p_namespace;
333 pstate->p_namespace = NIL;
337 sub_rtable = NIL; /* not used, but keep compiler quiet */
342 * Must get write lock on INSERT target table before scanning SELECT,
343 * else we will grab the wrong kind of initial lock if the target
344 * table is also mentioned in the SELECT part. Note that the target
345 * table is not added to the joinlist or namespace.
347 qry->resultRelation = setTargetTable(pstate, stmt->relname,
351 * Is it INSERT ... SELECT or INSERT ... VALUES?
353 if (stmt->selectStmt)
355 ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
361 * Process the source SELECT.
363 * It is important that this be handled just like a standalone
364 * SELECT; otherwise the behavior of SELECT within INSERT might be
365 * different from a stand-alone SELECT. (Indeed, Postgres up
366 * through 6.5 had bugs of just that nature...)
368 sub_pstate->p_rtable = sub_rtable;
369 sub_pstate->p_namespace = sub_namespace;
371 selectQuery = transformStmt(sub_pstate, stmt->selectStmt);
373 release_pstate_resources(sub_pstate);
376 Assert(IsA(selectQuery, Query));
377 Assert(selectQuery->commandType == CMD_SELECT);
378 if (selectQuery->into || selectQuery->isPortal)
379 elog(ERROR, "INSERT ... SELECT may not specify INTO");
382 * Make the source be a subquery in the INSERT's rangetable, and
383 * add it to the INSERT's joinlist.
385 rte = addRangeTableEntryForSubquery(pstate,
387 makeAttr("*SELECT*", NULL),
389 rtr = makeNode(RangeTblRef);
390 /* assume new rte is at end */
391 rtr->rtindex = length(pstate->p_rtable);
392 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
393 pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
396 * Generate a targetlist for the INSERT that selects all the
397 * non-resjunk columns from the subquery. (We need this to be
398 * separate from the subquery's tlist because we may add columns,
399 * insert datatype coercions, etc.)
401 * HACK: constants in the INSERT's targetlist are copied up as-is
402 * rather than being referenced as subquery outputs. This is
403 * mainly to ensure that when we try to coerce them to the target
404 * column's datatype, the right things happen for UNKNOWN
405 * constants. Otherwise this fails: INSERT INTO foo SELECT 'bar',
408 qry->targetList = NIL;
409 foreach(tl, selectQuery->targetList)
411 TargetEntry *tle = (TargetEntry *) lfirst(tl);
412 Resdom *resnode = tle->resdom;
415 if (resnode->resjunk)
417 if (tle->expr && IsA(tle->expr, Const))
420 expr = (Node *) makeVar(rtr->rtindex,
425 resnode = copyObject(resnode);
426 resnode->resno = (AttrNumber) pstate->p_last_resno++;
427 qry->targetList = lappend(qry->targetList,
428 makeTargetEntry(resnode, expr));
435 * For INSERT ... VALUES, transform the given list of values to
436 * form a targetlist for the INSERT.
438 qry->targetList = transformTargetList(pstate, stmt->targetList);
442 * Now we are done with SELECT-like processing, and can get on with
443 * transforming the target list to match the INSERT target columns.
446 /* Prepare to assign non-conflicting resnos to resjunk attributes */
447 if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
448 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
450 /* Validate stmt->cols list, or build default list if no list given */
451 icolumns = checkInsertTargets(pstate, stmt->cols, &attrnos);
454 * Prepare columns for assignment to target table.
458 foreach(tl, qry->targetList)
460 TargetEntry *tle = (TargetEntry *) lfirst(tl);
463 Assert(!tle->resdom->resjunk);
464 if (icolumns == NIL || attnos == NIL)
465 elog(ERROR, "INSERT has more expressions than target columns");
466 id = (Ident *) lfirst(icolumns);
467 updateTargetListEntry(pstate, tle, id->name, lfirsti(attnos),
470 icolumns = lnext(icolumns);
471 attnos = lnext(attnos);
475 * It is possible that the targetlist has fewer entries than were in
476 * the columns list. We do not consider this an error (perhaps we
477 * should, if the columns list was explictly given?). We must
478 * truncate the attrnos list to only include the attrs actually
479 * provided, else we will fail to apply defaults for them below.
482 attrnos = ltruncate(numuseratts, attrnos);
485 * Add targetlist items to assign DEFAULT values to any columns that
486 * have defaults and were not assigned to by the user.
488 * XXX wouldn't it make more sense to do this further downstream, after
489 * the rule rewriter? As is, altering a column default will not
490 * change the behavior of INSERTs in already-defined rules.
492 rd_att = pstate->p_target_relation->rd_att;
493 if (rd_att->constr && rd_att->constr->num_defval > 0)
495 Form_pg_attribute *att = rd_att->attrs;
496 AttrDefault *defval = rd_att->constr->defval;
497 int ndef = rd_att->constr->num_defval;
501 AttrNumber attrno = defval[ndef].adnum;
502 Form_pg_attribute thisatt = att[attrno - 1];
505 if (intMember((int) attrno, attrnos))
506 continue; /* there was a user-specified value */
509 * No user-supplied value, so add a targetentry with DEFAULT
510 * expr and correct data for the target column.
512 te = makeTargetEntry(
516 pstrdup(NameStr(thisatt->attname)),
518 stringToNode(defval[ndef].adbin));
519 qry->targetList = lappend(qry->targetList, te);
522 * Make sure the value is coerced to the target column type
523 * (might not be right type if it's not a constant!)
525 updateTargetListEntry(pstate, te, te->resdom->resname, attrno,
530 /* done building the range table and jointree */
531 qry->rtable = pstate->p_rtable;
532 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
534 qry->hasSubLinks = pstate->p_hasSubLinks;
535 qry->hasAggs = pstate->p_hasAggs;
536 if (pstate->p_hasAggs)
537 parseCheckAggregates(pstate, qry, NULL);
545 * Create a name for an implicitly created index, sequence, constraint, etc.
547 * The parameters are: the original table name, the original field name, and
548 * a "type" string (such as "seq" or "pkey"). The field name and/or type
549 * can be NULL if not relevant.
551 * The result is a palloc'd string.
553 * The basic result we want is "name1_name2_type", omitting "_name2" or
554 * "_type" when those parameters are NULL. However, we must generate
555 * a name with less than NAMEDATALEN characters! So, we truncate one or
556 * both names if necessary to make a short-enough string. The type part
557 * is never truncated (so it had better be reasonably short).
559 * To reduce the probability of collisions, we might someday add more
560 * smarts to this routine, like including some "hash" characters computed
561 * from the truncated characters. Currently it seems best to keep it simple,
562 * so that the generated names are easily predictable by a person.
565 makeObjectName(char *name1, char *name2, char *typename)
568 int overhead = 0; /* chars needed for type and underscores */
569 int availchars; /* chars available for name(s) */
570 int name1chars; /* chars allocated to name1 */
571 int name2chars; /* chars allocated to name2 */
574 name1chars = strlen(name1);
577 name2chars = strlen(name2);
578 overhead++; /* allow for separating underscore */
583 overhead += strlen(typename) + 1;
585 availchars = NAMEDATALEN - 1 - overhead;
588 * If we must truncate, preferentially truncate the longer name. This
589 * logic could be expressed without a loop, but it's simple and
592 while (name1chars + name2chars > availchars)
594 if (name1chars > name2chars)
602 name1chars = pg_mbcliplen(name1, name1chars, name1chars);
604 name2chars = pg_mbcliplen(name2, name2chars, name2chars);
607 /* Now construct the string using the chosen lengths */
608 name = palloc(name1chars + name2chars + overhead + 1);
609 strncpy(name, name1, name1chars);
614 strncpy(name + ndx, name2, name2chars);
620 strcpy(name + ndx, typename);
629 CreateIndexName(char *table_name, char *column_name,
630 char *label, List *indices)
635 char typename[NAMEDATALEN];
638 * The type name for makeObjectName is label, or labelN if that's
639 * necessary to prevent collisions among multiple indexes for the same
640 * table. Note there is no check for collisions with already-existing
641 * indexes, only among the indexes we're about to create now; this
642 * ought to be improved someday.
644 strcpy(typename, label);
648 iname = makeObjectName(table_name, column_name, typename);
650 foreach(ilist, indices)
652 IndexStmt *index = lfirst(ilist);
654 if (index->idxname != NULL &&
655 strcmp(iname, index->idxname) == 0)
658 /* ran through entire list? then no name conflict found so done */
662 /* found a conflict, so try a new name component */
664 sprintf(typename, "%s%d", label, ++pass);
671 * transformCreateStmt -
672 * transforms the "create table" statement
673 * SQL92 allows constraints to be scattered all over, so thumb through
674 * the columns and collect all constraints into one place.
675 * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
676 * then expand those into multiple IndexStmt blocks.
677 * - thomas 1997-12-02
680 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
690 Constraint *constraint;
691 List *fkconstraints, /* List of FOREIGN KEY constraints to */
692 *fkclist; /* add finally */
693 FkConstraint *fkconstraint;
696 List *blist = NIL; /* "before list" of things to do before
697 * creating the table */
698 List *ilist = NIL; /* "index list" of things to do after
699 * creating the table */
706 q->commandType = CMD_UTILITY;
709 constraints = stmt->constraints;
714 * Run through each primary element in the table creation clause
716 foreach(elements, stmt->tableElts)
718 element = lfirst(elements);
719 switch (nodeTag(element))
722 column = (ColumnDef *) element;
723 columns = lappend(columns, column);
725 transformColumnType(pstate, column);
727 /* Special case SERIAL type? */
728 if (column->is_sequence)
733 FuncCall *funccallnode;
734 CreateSeqStmt *sequence;
737 * Create appropriate constraints for SERIAL. We do
738 * this in full, rather than shortcutting, so that we
739 * will detect any conflicting constraints the user
740 * wrote (like a different DEFAULT).
742 sname = makeObjectName(stmt->relname, column->colname,
746 * Create an expression tree representing the function
747 * call nextval('"sequencename"')
749 qstring = palloc(strlen(sname) + 2 + 1);
750 sprintf(qstring, "\"%s\"", sname);
751 snamenode = makeNode(A_Const);
752 snamenode->val.type = T_String;
753 snamenode->val.val.str = qstring;
754 funccallnode = makeNode(FuncCall);
755 funccallnode->funcname = "nextval";
756 funccallnode->args = makeList1(snamenode);
757 funccallnode->agg_star = false;
758 funccallnode->agg_distinct = false;
760 constraint = makeNode(Constraint);
761 constraint->contype = CONSTR_DEFAULT;
762 constraint->name = sname;
763 constraint->raw_expr = (Node *) funccallnode;
764 constraint->cooked_expr = NULL;
765 constraint->keys = NIL;
766 column->constraints = lappend(column->constraints,
769 constraint = makeNode(Constraint);
770 constraint->contype = CONSTR_UNIQUE;
771 constraint->name = NULL; /* assign later */
772 column->constraints = lappend(column->constraints,
775 constraint = makeNode(Constraint);
776 constraint->contype = CONSTR_NOTNULL;
777 column->constraints = lappend(column->constraints,
780 sequence = makeNode(CreateSeqStmt);
781 sequence->seqname = pstrdup(sname);
782 sequence->options = NIL;
784 elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
785 sequence->seqname, stmt->relname, column->colname);
787 blist = lappend(blist, sequence);
790 /* Process column constraints, if any... */
791 transformConstraintAttrs(column->constraints);
793 saw_nullable = false;
795 foreach(clist, column->constraints)
797 constraint = lfirst(clist);
800 * If this column constraint is a FOREIGN KEY
801 * constraint, then we fill in the current attributes
802 * name and throw it into the list of FK constraints
803 * to be processed later.
805 if (IsA(constraint, FkConstraint))
807 Ident *id = makeNode(Ident);
809 id->name = column->colname;
810 id->indirection = NIL;
813 fkconstraint = (FkConstraint *) constraint;
814 fkconstraint->fk_attrs = makeList1(id);
816 fkconstraints = lappend(fkconstraints, constraint);
820 switch (constraint->contype)
823 if (saw_nullable && column->is_not_null)
824 elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
825 " for '%s.%s'", stmt->relname, column->colname);
826 column->is_not_null = FALSE;
831 if (saw_nullable && !column->is_not_null)
832 elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
833 " for '%s.%s'", stmt->relname, column->colname);
834 column->is_not_null = TRUE;
839 if (column->raw_default != NULL)
840 elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
841 " for '%s.%s'", stmt->relname, column->colname);
842 column->raw_default = constraint->raw_expr;
843 Assert(constraint->cooked_expr == NULL);
847 if (constraint->name == NULL)
848 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
849 if (constraint->keys == NIL)
851 key = makeNode(Ident);
852 key->name = pstrdup(column->colname);
853 constraint->keys = makeList1(key);
855 dlist = lappend(dlist, constraint);
859 if (constraint->name == NULL)
860 constraint->name = makeObjectName(stmt->relname, column->colname, "key");
861 if (constraint->keys == NIL)
863 key = makeNode(Ident);
864 key->name = pstrdup(column->colname);
865 constraint->keys = makeList1(key);
867 dlist = lappend(dlist, constraint);
871 if (constraint->name == NULL)
872 constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
873 constraints = lappend(constraints, constraint);
876 case CONSTR_ATTR_DEFERRABLE:
877 case CONSTR_ATTR_NOT_DEFERRABLE:
878 case CONSTR_ATTR_DEFERRED:
879 case CONSTR_ATTR_IMMEDIATE:
880 /* transformConstraintAttrs took care of these */
884 elog(ERROR, "parser: unrecognized constraint (internal error)");
891 constraint = (Constraint *) element;
892 switch (constraint->contype)
895 if (constraint->name == NULL)
896 constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
897 dlist = lappend(dlist, constraint);
901 dlist = lappend(dlist, constraint);
905 constraints = lappend(constraints, constraint);
911 case CONSTR_ATTR_DEFERRABLE:
912 case CONSTR_ATTR_NOT_DEFERRABLE:
913 case CONSTR_ATTR_DEFERRED:
914 case CONSTR_ATTR_IMMEDIATE:
915 elog(ERROR, "parser: illegal context for constraint (internal error)");
919 elog(ERROR, "parser: unrecognized constraint (internal error)");
927 * Table level FOREIGN KEY constraints are already
928 * complete. Just remember for later.
930 fkconstraints = lappend(fkconstraints, element);
934 elog(ERROR, "parser: unrecognized node (internal error)");
938 stmt->tableElts = columns;
939 stmt->constraints = constraints;
941 /* Now run through the "deferred list" to complete the query transformation.
942 * For PRIMARY KEY, mark each column as NOT NULL and create an index.
943 * For UNIQUE, create an index as for PRIMARY KEY, but do not insist on
948 constraint = lfirst(dlist);
949 Assert(IsA(constraint, Constraint));
950 Assert((constraint->contype == CONSTR_PRIMARY)
951 || (constraint->contype == CONSTR_UNIQUE));
953 index = makeNode(IndexStmt);
955 index->unique = TRUE;
956 index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE : FALSE);
960 elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
961 " for table '%s' are not allowed", stmt->relname);
965 if (constraint->name != NULL)
966 index->idxname = pstrdup(constraint->name);
967 else if (constraint->contype == CONSTR_PRIMARY)
968 index->idxname = makeObjectName(stmt->relname, NULL, "pkey");
970 index->idxname = NULL; /* will set it later */
972 index->relname = stmt->relname;
973 index->accessMethod = "btree";
974 index->indexParams = NIL;
975 index->withClause = NIL;
976 index->whereClause = NULL;
978 foreach(keys, constraint->keys)
982 key = (Ident *) lfirst(keys);
983 Assert(IsA(key, Ident));
985 foreach(columns, stmt->tableElts)
987 column = lfirst(columns);
988 Assert(IsA(column, ColumnDef));
989 if (strcmp(column->colname, key->name) == 0)
997 /* found column in the new table; force it to be NOT NULL */
998 if (constraint->contype == CONSTR_PRIMARY)
999 column->is_not_null = TRUE;
1003 /* try inherited tables */
1004 List *inhRelnames = stmt->inhRelnames;
1007 foreach(inher, inhRelnames)
1009 Value *inh = lfirst(inher);
1013 Assert(IsA(inh, String));
1014 rel = heap_openr(strVal(inh), AccessShareLock);
1015 if (rel->rd_rel->relkind != RELKIND_RELATION)
1016 elog(ERROR, "inherited table \"%s\" is not a relation",
1018 for (count = 0; count < rel->rd_att->natts; count++)
1020 Form_pg_attribute inhattr = rel->rd_att->attrs[count];
1021 char *inhname = NameStr(inhattr->attname);
1023 if (strcmp(key->name, inhname) == 0)
1028 * If the column is inherited, we currently
1029 * have no easy way to force it to be NOT
1030 * NULL. Only way I can see to fix this would
1031 * be to convert the inherited-column info to
1032 * ColumnDef nodes before we reach this point,
1033 * and then create the table from those nodes
1034 * rather than referencing the parent tables
1035 * later. That would likely be cleaner, but
1036 * too much work to contemplate right now.
1037 * Instead, raise an error if the inherited
1038 * column won't be NOT NULL. (Would a NOTICE
1039 * be more reasonable?)
1041 if (constraint->contype == CONSTR_PRIMARY &&
1042 !inhattr->attnotnull)
1043 elog(ERROR, "inherited attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL",
1048 heap_close(rel, NoLock);
1055 elog(ERROR, "CREATE TABLE: column \"%s\" named in key does not exist",
1058 iparam = makeNode(IndexElem);
1059 iparam->name = pstrdup(key->name);
1061 iparam->class = NULL;
1062 index->indexParams = lappend(index->indexParams, iparam);
1065 ilist = lappend(ilist, index);
1066 dlist = lnext(dlist);
1070 * Scan the index list and remove any redundant index specifications.
1071 * This can happen if, for instance, the user writes SERIAL PRIMARY
1072 * KEY or SERIAL UNIQUE. A strict reading of SQL92 would suggest
1073 * raising an error instead, but that strikes me as too
1074 * anal-retentive. - tgl 2001-02-14
1080 /* Make sure we keep the PKEY index in preference to others... */
1081 ilist = makeList1(pkey);
1083 while (dlist != NIL)
1085 index = lfirst(dlist);
1087 /* if it's pkey, it's already in ilist */
1093 foreach(priorlist, ilist)
1095 IndexStmt *priorindex = lfirst(priorlist);
1097 if (equal(index->indexParams, priorindex->indexParams))
1101 * If the prior index is as yet unnamed, and this one
1102 * is named, then transfer the name to the prior
1103 * index. This ensures that if we have named and
1104 * unnamed constraints, we'll use (at least one of)
1105 * the names for the index.
1107 if (priorindex->idxname == NULL)
1108 priorindex->idxname = index->idxname;
1115 ilist = lappend(ilist, index);
1118 dlist = lnext(dlist);
1122 * Finally, select unique names for all not-previously-named indices,
1123 * and display notice messages.
1126 while (dlist != NIL)
1128 index = lfirst(dlist);
1130 if (index->idxname == NULL && index->indexParams != NIL)
1132 iparam = lfirst(index->indexParams);
1133 index->idxname = CreateIndexName(stmt->relname, iparam->name,
1136 if (index->idxname == NULL) /* should not happen */
1137 elog(ERROR, "CREATE TABLE: failed to make implicit index name");
1139 elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
1140 (index->primary ? "PRIMARY KEY" : "UNIQUE"),
1141 index->idxname, stmt->relname);
1143 dlist = lnext(dlist);
1146 q->utilityStmt = (Node *) stmt;
1147 extras_before = blist;
1148 extras_after = ilist;
1151 * Now process the FOREIGN KEY constraints and add appropriate queries
1152 * to the extras_after statements list.
1154 if (fkconstraints != NIL)
1156 CreateTrigStmt *fk_trigger;
1160 Oid pktypoid[INDEX_MAX_KEYS];
1161 Oid fktypoid[INDEX_MAX_KEYS];
1164 for (i=0; i<INDEX_MAX_KEYS; i++) {
1165 pktypoid[i]=fktypoid[i]=0;
1167 elog(NOTICE, "CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)");
1169 foreach(fkclist, fkconstraints)
1171 fkconstraint = (FkConstraint *) lfirst(fkclist);
1174 * If the constraint has no name, set it to <unnamed>
1177 if (fkconstraint->constr_name == NULL)
1178 fkconstraint->constr_name = "<unnamed>";
1181 * Check to see if the attributes mentioned by the constraint
1182 * actually exist on this table.
1184 if (fkconstraint->fk_attrs != NIL)
1190 Ident *fkattr = NULL;
1193 foreach(fkattrs, fkconstraint->fk_attrs)
1196 fkattr = lfirst(fkattrs);
1197 foreach(cols, stmt->tableElts)
1200 if (strcmp(col->colname, fkattr->name) == 0)
1202 char *buff=TypeNameToInternalName(col->typename);
1203 Oid type=typenameTypeId(buff);
1204 if (!OidIsValid(type)) {
1205 elog(ERROR, "Unable to lookup type %s", col->typename->name);
1207 fktypoid[attnum++]=type;
1214 List *inhRelnames = stmt->inhRelnames;
1217 foreach(inher, inhRelnames)
1219 Value *inh = lfirst(inher);
1222 Assert(IsA(inh, String));
1223 rel = heap_openr(strVal(inh), AccessShareLock);
1224 if (rel->rd_rel->relkind != RELKIND_RELATION)
1225 elog(ERROR, "inherited table \"%s\" is not a relation",
1227 for (count = 0; count < rel->rd_att->natts; count++)
1229 char *name = NameStr(rel->rd_att->attrs[count]->attname);
1231 if (strcmp(fkattr->name, name) == 0)
1233 fktypoid[attnum++]=rel->rd_att->attrs[count]->atttypid;
1238 heap_close(rel, NoLock);
1247 elog(ERROR, "columns referenced in foreign key constraint not found.");
1251 * If the attribute list for the referenced table was omitted,
1252 * lookup for the definition of the primary key. If the
1253 * referenced table is this table, use the definition we found
1254 * above, rather than looking to the system tables.
1257 if (fkconstraint->fk_attrs != NIL && fkconstraint->pk_attrs == NIL)
1259 if (strcmp(fkconstraint->pktable_name, stmt->relname) != 0)
1260 transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
1261 else if (pkey != NULL)
1263 List *pkey_attr = pkey->indexParams;
1271 foreach(attr, pkey_attr)
1273 ielem = lfirst(attr);
1274 pkattr = (Ident *) makeNode(Ident);
1275 pkattr->name = pstrdup(ielem->name);
1276 pkattr->indirection = NIL;
1277 pkattr->isRel = false;
1278 fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
1279 foreach (findattr, stmt->tableElts) {
1280 col=lfirst(findattr);
1281 if (strcmp(col->colname, ielem->name)==0) {
1282 char *buff=TypeNameToInternalName(col->typename);
1283 Oid type=typenameTypeId(buff);
1284 if (!OidIsValid(type)) {
1285 elog(ERROR, "Unable to lookup type %s", col->typename->name);
1287 pktypoid[attnum++]=type; /* need to convert typename */
1295 elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
1296 fkconstraint->pktable_name);
1301 if (strcmp(fkconstraint->pktable_name, stmt->relname) != 0)
1302 transformFkeyCheckAttrs(fkconstraint, pktypoid);
1305 /* Get a unique/pk constraint from above */
1309 foreach(index, ilist)
1311 IndexStmt *ind = lfirst(index);
1324 foreach(indparms, ind->indexParams)
1326 if (count != length(fkconstraint->pk_attrs))
1330 foreach(pkattrs, fkconstraint->pk_attrs)
1333 pkattr = lfirst(pkattrs);
1334 foreach(indparms, ind->indexParams)
1336 indparm = lfirst(indparms);
1337 if (strcmp(indparm->name, pkattr->name) == 0)
1339 foreach (findattr, stmt->tableElts) {
1340 col=lfirst(findattr);
1341 if (strcmp(col->colname, indparm->name)==0) {
1342 char *buff=TypeNameToInternalName(col->typename);
1343 Oid type=typenameTypeId(buff);
1344 if (!OidIsValid(type)) {
1345 elog(ERROR, "Unable to lookup type %s", col->typename->name);
1347 pktypoid[attnum++]=type;
1354 List *inhRelnames=stmt->inhRelnames;
1356 foreach (inher, inhRelnames) {
1357 Value *inh=lfirst(inher);
1359 Assert(IsA(inh, String));
1360 rel=heap_openr(strVal(inh), AccessShareLock);
1361 if (rel->rd_rel->relkind!=RELKIND_RELATION)
1362 elog(ERROR, "inherited table \"%s\" is not a relation", strVal(inh));
1363 for (count=0; count<rel->rd_att->natts; count++) {
1364 char *name=NameStr(rel->rd_att->attrs[count]->attname);
1365 if (strcmp(pkattr->name, name)==0) {
1366 pktypoid[attnum++]=rel->rd_att->attrs[count]->atttypid;
1371 heap_close(rel, NoLock);
1388 elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
1389 fkconstraint->pktable_name);
1393 for (i = 0; i < INDEX_MAX_KEYS && fktypoid[i] != 0; i++) {
1395 * fktypoid[i] is the foreign key table's i'th element's type oid
1396 * pktypoid[i] is the primary key table's i'th element's type oid
1397 * We let oper() do our work for us, including elog(ERROR) if the
1398 * types don't compare with =
1400 Operator o=oper("=", fktypoid[i], pktypoid[i], false);
1404 * Build a CREATE CONSTRAINT TRIGGER statement for the CHECK
1408 fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
1409 fk_trigger->trigname = fkconstraint->constr_name;
1410 fk_trigger->relname = stmt->relname;
1411 fk_trigger->funcname = "RI_FKey_check_ins";
1412 fk_trigger->before = false;
1413 fk_trigger->row = true;
1414 fk_trigger->actions[0] = 'i';
1415 fk_trigger->actions[1] = 'u';
1416 fk_trigger->actions[2] = '\0';
1417 fk_trigger->lang = NULL;
1418 fk_trigger->text = NULL;
1420 fk_trigger->attr = NIL;
1421 fk_trigger->when = NULL;
1422 fk_trigger->isconstraint = true;
1423 fk_trigger->deferrable = fkconstraint->deferrable;
1424 fk_trigger->initdeferred = fkconstraint->initdeferred;
1425 fk_trigger->constrrelname = fkconstraint->pktable_name;
1427 fk_trigger->args = NIL;
1428 fk_trigger->args = lappend(fk_trigger->args,
1429 makeString(fkconstraint->constr_name));
1430 fk_trigger->args = lappend(fk_trigger->args,
1431 makeString(stmt->relname));
1432 fk_trigger->args = lappend(fk_trigger->args,
1433 makeString(fkconstraint->pktable_name));
1434 fk_trigger->args = lappend(fk_trigger->args,
1435 makeString(fkconstraint->match_type));
1436 fk_attr = fkconstraint->fk_attrs;
1437 pk_attr = fkconstraint->pk_attrs;
1438 if (length(fk_attr) != length(pk_attr))
1440 elog(NOTICE, "Illegal FOREIGN KEY definition REFERENCES \"%s\"",
1441 fkconstraint->pktable_name);
1442 elog(ERROR, "number of key attributes in referenced table must be equal to foreign key");
1444 while (fk_attr != NIL)
1446 id = (Ident *) lfirst(fk_attr);
1447 fk_trigger->args = lappend(fk_trigger->args,
1448 makeString(id->name));
1450 id = (Ident *) lfirst(pk_attr);
1451 fk_trigger->args = lappend(fk_trigger->args,
1452 makeString(id->name));
1454 fk_attr = lnext(fk_attr);
1455 pk_attr = lnext(pk_attr);
1458 extras_after = lappend(extras_after, (Node *) fk_trigger);
1461 * Build a CREATE CONSTRAINT TRIGGER statement for the ON
1462 * DELETE action fired on the PK table !!!
1465 fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
1466 fk_trigger->trigname = fkconstraint->constr_name;
1467 fk_trigger->relname = fkconstraint->pktable_name;
1468 fk_trigger->before = false;
1469 fk_trigger->row = true;
1470 fk_trigger->actions[0] = 'd';
1471 fk_trigger->actions[1] = '\0';
1472 fk_trigger->lang = NULL;
1473 fk_trigger->text = NULL;
1475 fk_trigger->attr = NIL;
1476 fk_trigger->when = NULL;
1477 fk_trigger->isconstraint = true;
1478 fk_trigger->deferrable = fkconstraint->deferrable;
1479 fk_trigger->initdeferred = fkconstraint->initdeferred;
1480 fk_trigger->constrrelname = stmt->relname;
1481 switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK)
1482 >> FKCONSTR_ON_DELETE_SHIFT)
1484 case FKCONSTR_ON_KEY_NOACTION:
1485 fk_trigger->funcname = "RI_FKey_noaction_del";
1487 case FKCONSTR_ON_KEY_RESTRICT:
1488 fk_trigger->deferrable = false;
1489 fk_trigger->initdeferred = false;
1490 fk_trigger->funcname = "RI_FKey_restrict_del";
1492 case FKCONSTR_ON_KEY_CASCADE:
1493 fk_trigger->funcname = "RI_FKey_cascade_del";
1495 case FKCONSTR_ON_KEY_SETNULL:
1496 fk_trigger->funcname = "RI_FKey_setnull_del";
1498 case FKCONSTR_ON_KEY_SETDEFAULT:
1499 fk_trigger->funcname = "RI_FKey_setdefault_del";
1502 elog(ERROR, "Only one ON DELETE action can be specified for FOREIGN KEY constraint");
1506 fk_trigger->args = NIL;
1507 fk_trigger->args = lappend(fk_trigger->args,
1508 makeString(fkconstraint->constr_name));
1509 fk_trigger->args = lappend(fk_trigger->args,
1510 makeString(stmt->relname));
1511 fk_trigger->args = lappend(fk_trigger->args,
1512 makeString(fkconstraint->pktable_name));
1513 fk_trigger->args = lappend(fk_trigger->args,
1514 makeString(fkconstraint->match_type));
1515 fk_attr = fkconstraint->fk_attrs;
1516 pk_attr = fkconstraint->pk_attrs;
1517 while (fk_attr != NIL)
1519 id = (Ident *) lfirst(fk_attr);
1520 fk_trigger->args = lappend(fk_trigger->args,
1521 makeString(id->name));
1523 id = (Ident *) lfirst(pk_attr);
1524 fk_trigger->args = lappend(fk_trigger->args,
1525 makeString(id->name));
1527 fk_attr = lnext(fk_attr);
1528 pk_attr = lnext(pk_attr);
1531 extras_after = lappend(extras_after, (Node *) fk_trigger);
1534 * Build a CREATE CONSTRAINT TRIGGER statement for the ON
1535 * UPDATE action fired on the PK table !!!
1538 fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
1539 fk_trigger->trigname = fkconstraint->constr_name;
1540 fk_trigger->relname = fkconstraint->pktable_name;
1541 fk_trigger->before = false;
1542 fk_trigger->row = true;
1543 fk_trigger->actions[0] = 'u';
1544 fk_trigger->actions[1] = '\0';
1545 fk_trigger->lang = NULL;
1546 fk_trigger->text = NULL;
1548 fk_trigger->attr = NIL;
1549 fk_trigger->when = NULL;
1550 fk_trigger->isconstraint = true;
1551 fk_trigger->deferrable = fkconstraint->deferrable;
1552 fk_trigger->initdeferred = fkconstraint->initdeferred;
1553 fk_trigger->constrrelname = stmt->relname;
1554 switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK)
1555 >> FKCONSTR_ON_UPDATE_SHIFT)
1557 case FKCONSTR_ON_KEY_NOACTION:
1558 fk_trigger->funcname = "RI_FKey_noaction_upd";
1560 case FKCONSTR_ON_KEY_RESTRICT:
1561 fk_trigger->deferrable = false;
1562 fk_trigger->initdeferred = false;
1563 fk_trigger->funcname = "RI_FKey_restrict_upd";
1565 case FKCONSTR_ON_KEY_CASCADE:
1566 fk_trigger->funcname = "RI_FKey_cascade_upd";
1568 case FKCONSTR_ON_KEY_SETNULL:
1569 fk_trigger->funcname = "RI_FKey_setnull_upd";
1571 case FKCONSTR_ON_KEY_SETDEFAULT:
1572 fk_trigger->funcname = "RI_FKey_setdefault_upd";
1575 elog(ERROR, "Only one ON UPDATE action can be specified for FOREIGN KEY constraint");
1579 fk_trigger->args = NIL;
1580 fk_trigger->args = lappend(fk_trigger->args,
1581 makeString(fkconstraint->constr_name));
1582 fk_trigger->args = lappend(fk_trigger->args,
1583 makeString(stmt->relname));
1584 fk_trigger->args = lappend(fk_trigger->args,
1585 makeString(fkconstraint->pktable_name));
1586 fk_trigger->args = lappend(fk_trigger->args,
1587 makeString(fkconstraint->match_type));
1588 fk_attr = fkconstraint->fk_attrs;
1589 pk_attr = fkconstraint->pk_attrs;
1590 while (fk_attr != NIL)
1592 id = (Ident *) lfirst(fk_attr);
1593 fk_trigger->args = lappend(fk_trigger->args,
1594 makeString(id->name));
1596 id = (Ident *) lfirst(pk_attr);
1597 fk_trigger->args = lappend(fk_trigger->args,
1598 makeString(id->name));
1600 fk_attr = lnext(fk_attr);
1601 pk_attr = lnext(pk_attr);
1604 extras_after = lappend(extras_after, (Node *) fk_trigger);
1609 } /* transformCreateStmt() */
1613 * transformIndexStmt -
1614 * transforms the qualification of the index statement
1617 transformIndexStmt(ParseState *pstate, IndexStmt *stmt)
1621 qry = makeNode(Query);
1622 qry->commandType = CMD_UTILITY;
1624 /* take care of the where clause */
1625 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1627 qry->hasSubLinks = pstate->p_hasSubLinks;
1629 stmt->rangetable = pstate->p_rtable;
1631 qry->utilityStmt = (Node *) stmt;
1637 * transformExtendStmt -
1638 * transform the qualifications of the Extend Index Statement
1642 transformExtendStmt(ParseState *pstate, ExtendStmt *stmt)
1646 qry = makeNode(Query);
1647 qry->commandType = CMD_UTILITY;
1649 /* take care of the where clause */
1650 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1652 qry->hasSubLinks = pstate->p_hasSubLinks;
1654 stmt->rangetable = pstate->p_rtable;
1656 qry->utilityStmt = (Node *) stmt;
1661 * transformRuleStmt -
1662 * transform a Create Rule Statement. The actions is a list of parse
1663 * trees which is transformed into a list of query trees.
1666 transformRuleStmt(ParseState *pstate, RuleStmt *stmt)
1669 RangeTblEntry *oldrte;
1670 RangeTblEntry *newrte;
1672 qry = makeNode(Query);
1673 qry->commandType = CMD_UTILITY;
1674 qry->utilityStmt = (Node *) stmt;
1677 * To avoid deadlock, make sure the first thing we do is grab
1678 * AccessExclusiveLock on the target relation. This will be needed by
1679 * DefineQueryRewrite(), and we don't want to grab a lesser lock
1680 * beforehand. We don't need to hold a refcount on the relcache
1683 heap_close(heap_openr(stmt->object->relname, AccessExclusiveLock),
1687 * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to
1688 * 2. Set up their RTEs in the main pstate for use in parsing the
1689 * rule qualification.
1691 Assert(pstate->p_rtable == NIL);
1692 oldrte = addRangeTableEntry(pstate, stmt->object->relname,
1693 makeAttr("*OLD*", NULL),
1695 newrte = addRangeTableEntry(pstate, stmt->object->relname,
1696 makeAttr("*NEW*", NULL),
1698 /* Must override addRangeTableEntry's default access-check flags */
1699 oldrte->checkForRead = false;
1700 newrte->checkForRead = false;
1703 * They must be in the namespace too for lookup purposes, but only add
1704 * the one(s) that are relevant for the current kind of rule. In an
1705 * UPDATE rule, quals must refer to OLD.field or NEW.field to be
1706 * unambiguous, but there's no need to be so picky for INSERT &
1707 * DELETE. (Note we marked the RTEs "inFromCl = true" above to allow
1708 * unqualified references to their fields.) We do not add them to the
1711 switch (stmt->event)
1714 addRTEtoQuery(pstate, oldrte, false, true);
1717 addRTEtoQuery(pstate, oldrte, false, true);
1718 addRTEtoQuery(pstate, newrte, false, true);
1721 addRTEtoQuery(pstate, newrte, false, true);
1724 addRTEtoQuery(pstate, oldrte, false, true);
1727 elog(ERROR, "transformRuleStmt: unexpected event type %d",
1732 /* take care of the where clause */
1733 stmt->whereClause = transformWhereClause(pstate, stmt->whereClause);
1735 if (length(pstate->p_rtable) != 2) /* naughty, naughty... */
1736 elog(ERROR, "Rule WHERE condition may not contain references to other relations");
1738 /* save info about sublinks in where clause */
1739 qry->hasSubLinks = pstate->p_hasSubLinks;
1742 * 'instead nothing' rules with a qualification need a query
1743 * rangetable so the rewrite handler can add the negated rule
1744 * qualification to the original query. We create a query with the new
1745 * command type CMD_NOTHING here that is treated specially by the
1748 if (stmt->actions == NIL)
1750 Query *nothing_qry = makeNode(Query);
1752 nothing_qry->commandType = CMD_NOTHING;
1753 nothing_qry->rtable = pstate->p_rtable;
1754 nothing_qry->jointree = makeFromExpr(NIL, NULL); /* no join wanted */
1756 stmt->actions = makeList1(nothing_qry);
1761 List *newactions = NIL;
1764 * transform each statement, like parse_analyze()
1766 foreach(oldactions, stmt->actions)
1768 Node *action = (Node *) lfirst(oldactions);
1769 ParseState *sub_pstate = make_parsestate(pstate->parentParseState);
1776 * Set up OLD/NEW in the rtable for this statement. The
1777 * entries are marked not inFromCl because we don't want them
1778 * to be referred to by unqualified field names nor "*" in the
1779 * rule actions. We must add them to the namespace, however,
1780 * or they won't be accessible at all. We decide later
1781 * whether to put them in the joinlist.
1783 oldrte = addRangeTableEntry(sub_pstate, stmt->object->relname,
1784 makeAttr("*OLD*", NULL),
1786 newrte = addRangeTableEntry(sub_pstate, stmt->object->relname,
1787 makeAttr("*NEW*", NULL),
1789 oldrte->checkForRead = false;
1790 newrte->checkForRead = false;
1791 addRTEtoQuery(sub_pstate, oldrte, false, true);
1792 addRTEtoQuery(sub_pstate, newrte, false, true);
1794 /* Transform the rule action statement */
1795 top_subqry = transformStmt(sub_pstate, action);
1798 * We cannot support utility-statement actions (eg NOTIFY)
1799 * with nonempty rule WHERE conditions, because there's no
1800 * way to make the utility action execute conditionally.
1802 if (top_subqry->commandType == CMD_UTILITY &&
1803 stmt->whereClause != NULL)
1804 elog(ERROR, "Rules with WHERE conditions may only have SELECT, INSERT, UPDATE, or DELETE actions");
1807 * If the action is INSERT...SELECT, OLD/NEW have been pushed
1808 * down into the SELECT, and that's what we need to look at.
1809 * (Ugly kluge ... try to fix this when we redesign
1812 sub_qry = getInsertSelectQuery(top_subqry, NULL);
1815 * Validate action's use of OLD/NEW, qual too
1818 rangeTableEntry_used((Node *) sub_qry, PRS2_OLD_VARNO, 0) ||
1819 rangeTableEntry_used(stmt->whereClause, PRS2_OLD_VARNO, 0);
1821 rangeTableEntry_used((Node *) sub_qry, PRS2_NEW_VARNO, 0) ||
1822 rangeTableEntry_used(stmt->whereClause, PRS2_NEW_VARNO, 0);
1824 switch (stmt->event)
1828 elog(ERROR, "ON SELECT rule may not use OLD");
1830 elog(ERROR, "ON SELECT rule may not use NEW");
1837 elog(ERROR, "ON INSERT rule may not use OLD");
1841 elog(ERROR, "ON DELETE rule may not use NEW");
1844 elog(ERROR, "transformRuleStmt: unexpected event type %d",
1850 * For efficiency's sake, add OLD to the rule action's
1851 * jointree only if it was actually referenced in the
1852 * statement or qual.
1854 * For INSERT, NEW is not really a relation (only a reference to
1855 * the to-be-inserted tuple) and should never be added to the
1858 * For UPDATE, we treat NEW as being another kind of reference to
1859 * OLD, because it represents references to *transformed*
1860 * tuples of the existing relation. It would be wrong to
1861 * enter NEW separately in the jointree, since that would
1862 * cause a double join of the updated relation. It's also
1863 * wrong to fail to make a jointree entry if only NEW and not
1866 if (has_old || (has_new && stmt->event == CMD_UPDATE))
1868 /* hack so we can use addRTEtoQuery() */
1869 sub_pstate->p_rtable = sub_qry->rtable;
1870 sub_pstate->p_joinlist = sub_qry->jointree->fromlist;
1871 addRTEtoQuery(sub_pstate, oldrte, true, false);
1872 sub_qry->jointree->fromlist = sub_pstate->p_joinlist;
1875 newactions = lappend(newactions, top_subqry);
1877 release_pstate_resources(sub_pstate);
1881 stmt->actions = newactions;
1889 * transformSelectStmt -
1890 * transforms a Select Statement
1892 * Note: this is also used for DECLARE CURSOR statements.
1895 transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
1897 Query *qry = makeNode(Query);
1900 qry->commandType = CMD_SELECT;
1902 if (stmt->portalname)
1904 /* DECLARE CURSOR */
1906 elog(ERROR, "DECLARE CURSOR must not specify INTO");
1907 if (stmt->forUpdate)
1908 elog(ERROR, "DECLARE/UPDATE is not supported"
1909 "\n\tCursors must be READ ONLY");
1912 * 15 august 1991 -- since 3.0 postgres does locking right, we
1913 * discovered that portals were violating locking protocol. portal
1914 * locks cannot span xacts. as a short-term fix, we installed the
1915 * check here. -- mao
1917 if (!IsTransactionBlock())
1918 elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
1920 qry->into = stmt->portalname;
1921 qry->isTemp = stmt->istemp;
1922 qry->isPortal = TRUE;
1923 qry->isBinary = stmt->binary; /* internal portal */
1928 qry->into = stmt->into;
1929 qry->isTemp = stmt->istemp;
1930 qry->isPortal = FALSE;
1931 qry->isBinary = FALSE;
1934 /* make FOR UPDATE clause available to addRangeTableEntry */
1935 pstate->p_forUpdate = stmt->forUpdate;
1937 /* process the FROM clause */
1938 transformFromClause(pstate, stmt->fromClause);
1940 /* transform targetlist and WHERE */
1941 qry->targetList = transformTargetList(pstate, stmt->targetList);
1943 qual = transformWhereClause(pstate, stmt->whereClause);
1946 * Initial processing of HAVING clause is just like WHERE clause.
1947 * Additional work will be done in optimizer/plan/planner.c.
1949 qry->havingQual = transformWhereClause(pstate, stmt->havingClause);
1951 qry->groupClause = transformGroupClause(pstate,
1955 qry->sortClause = transformSortClause(pstate,
1959 qry->distinctClause = transformDistinctClause(pstate,
1960 stmt->distinctClause,
1964 qry->limitOffset = stmt->limitOffset;
1965 qry->limitCount = stmt->limitCount;
1967 qry->hasSubLinks = pstate->p_hasSubLinks;
1968 qry->hasAggs = pstate->p_hasAggs;
1969 if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
1970 parseCheckAggregates(pstate, qry, qual);
1972 qry->rtable = pstate->p_rtable;
1973 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
1975 if (stmt->forUpdate != NIL)
1976 transformForUpdate(qry, stmt->forUpdate);
1982 * transformSetOperationsStmt -
1983 * transforms a set-operations tree
1985 * A set-operation tree is just a SELECT, but with UNION/INTERSECT/EXCEPT
1986 * structure to it. We must transform each leaf SELECT and build up a top-
1987 * level Query that contains the leaf SELECTs as subqueries in its rangetable.
1988 * The tree of set operations is converted into the setOperations field of
1989 * the top-level Query.
1991 static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
1993 Query *qry = makeNode(Query);
1994 SelectStmt *leftmostSelect;
1996 Query *leftmostQuery;
1997 SetOperationStmt *sostmt;
2015 qry->commandType = CMD_SELECT;
2018 * Find leftmost leaf SelectStmt; extract the one-time-only items from
2019 * it and from the top-level node.
2021 leftmostSelect = stmt->larg;
2022 while (leftmostSelect && leftmostSelect->op != SETOP_NONE)
2023 leftmostSelect = leftmostSelect->larg;
2024 Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
2025 leftmostSelect->larg == NULL);
2026 into = leftmostSelect->into;
2027 istemp = leftmostSelect->istemp;
2028 portalname = stmt->portalname;
2029 binary = stmt->binary;
2031 /* clear them to prevent complaints in transformSetOperationTree() */
2032 leftmostSelect->into = NULL;
2033 leftmostSelect->istemp = false;
2034 stmt->portalname = NULL;
2035 stmt->binary = false;
2038 * These are not one-time, exactly, but we want to process them here
2039 * and not let transformSetOperationTree() see them --- else it'll
2040 * just recurse right back here!
2042 sortClause = stmt->sortClause;
2043 limitOffset = stmt->limitOffset;
2044 limitCount = stmt->limitCount;
2045 forUpdate = stmt->forUpdate;
2047 stmt->sortClause = NIL;
2048 stmt->limitOffset = NULL;
2049 stmt->limitCount = NULL;
2050 stmt->forUpdate = NIL;
2052 /* We don't support forUpdate with set ops at the moment. */
2054 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2057 * Recursively transform the components of the tree.
2059 sostmt = (SetOperationStmt *) transformSetOperationTree(pstate, stmt);
2060 Assert(sostmt && IsA(sostmt, SetOperationStmt));
2061 qry->setOperations = (Node *) sostmt;
2064 * Re-find leftmost SELECT (now it's a sub-query in rangetable)
2066 node = sostmt->larg;
2067 while (node && IsA(node, SetOperationStmt))
2068 node = ((SetOperationStmt *) node)->larg;
2069 Assert(node && IsA(node, RangeTblRef));
2070 leftmostRTI = ((RangeTblRef *) node)->rtindex;
2071 leftmostQuery = rt_fetch(leftmostRTI, pstate->p_rtable)->subquery;
2072 Assert(leftmostQuery != NULL);
2075 * Generate dummy targetlist for outer query using column names of
2076 * leftmost select and common datatypes of topmost set operation. Also
2077 * make lists of the dummy vars and their names for use in parsing
2080 qry->targetList = NIL;
2083 lefttl = leftmostQuery->targetList;
2084 foreach(dtlist, sostmt->colTypes)
2086 Oid colType = (Oid) lfirsti(dtlist);
2087 Resdom *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
2088 char *colName = pstrdup(leftResdom->resname);
2092 resdom = makeResdom((AttrNumber) pstate->p_last_resno++,
2097 expr = (Node *) makeVar(leftmostRTI,
2102 qry->targetList = lappend(qry->targetList,
2103 makeTargetEntry(resdom, expr));
2104 targetvars = lappend(targetvars, expr);
2105 targetnames = lappend(targetnames, makeString(colName));
2106 lefttl = lnext(lefttl);
2110 * Insert one-time items into top-level query
2112 * This needs to agree with transformSelectStmt!
2116 /* DECLARE CURSOR */
2118 elog(ERROR, "DECLARE CURSOR must not specify INTO");
2120 elog(ERROR, "DECLARE/UPDATE is not supported"
2121 "\n\tCursors must be READ ONLY");
2124 * 15 august 1991 -- since 3.0 postgres does locking right, we
2125 * discovered that portals were violating locking protocol. portal
2126 * locks cannot span xacts. as a short-term fix, we installed the
2127 * check here. -- mao
2129 if (!IsTransactionBlock())
2130 elog(ERROR, "DECLARE CURSOR may only be used in begin/end transaction blocks");
2132 qry->into = portalname;
2133 qry->isTemp = istemp;
2134 qry->isPortal = TRUE;
2135 qry->isBinary = binary; /* internal portal */
2141 qry->isTemp = istemp;
2142 qry->isPortal = FALSE;
2143 qry->isBinary = FALSE;
2147 * As a first step towards supporting sort clauses that are
2148 * expressions using the output columns, generate a namespace entry
2149 * that makes the output columns visible. A JoinExpr node is handy
2150 * for this, since we can easily control the Vars generated upon
2153 * Note: we don't yet do anything useful with such cases, but at least
2154 * "ORDER BY upper(foo)" will draw the right error message rather than
2157 jnode = makeNode(JoinExpr);
2158 jnode->colnames = targetnames;
2159 jnode->colvars = targetvars;
2161 sv_namespace = pstate->p_namespace;
2162 pstate->p_namespace = makeList1(jnode);
2165 * For now, we don't support resjunk sort clauses on the output of a
2166 * setOperation tree --- you can only use the SQL92-spec options of
2167 * selecting an output column by name or number. Enforce by checking
2168 * that transformSortClause doesn't add any items to tlist.
2170 tllen = length(qry->targetList);
2172 qry->sortClause = transformSortClause(pstate,
2176 pstate->p_namespace = sv_namespace;
2178 if (tllen != length(qry->targetList))
2179 elog(ERROR, "ORDER BY on a UNION/INTERSECT/EXCEPT result must be on one of the result columns");
2181 qry->limitOffset = limitOffset;
2182 qry->limitCount = limitCount;
2184 qry->hasSubLinks = pstate->p_hasSubLinks;
2185 qry->hasAggs = pstate->p_hasAggs;
2186 if (pstate->p_hasAggs || qry->groupClause || qry->havingQual)
2187 parseCheckAggregates(pstate, qry, NULL);
2189 qry->rtable = pstate->p_rtable;
2190 qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
2192 if (forUpdate != NIL)
2193 transformForUpdate(qry, forUpdate);
2199 * transformSetOperationTree
2200 * Recursively transform leaves and internal nodes of a set-op tree
2203 transformSetOperationTree(ParseState *pstate, SelectStmt *stmt)
2207 Assert(stmt && IsA(stmt, SelectStmt));
2210 * Validity-check both leaf and internal SELECTs for disallowed ops.
2213 elog(ERROR, "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT");
2214 if (stmt->portalname) /* should not happen */
2215 elog(ERROR, "Portal may not appear in UNION/INTERSECT/EXCEPT");
2216 /* We don't support forUpdate with set ops at the moment. */
2217 if (stmt->forUpdate)
2218 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2221 * If an internal node of a set-op tree has ORDER BY, UPDATE, or LIMIT
2222 * clauses attached, we need to treat it like a leaf node to generate
2223 * an independent sub-Query tree. Otherwise, it can be represented by
2224 * a SetOperationStmt node underneath the parent Query.
2226 if (stmt->op == SETOP_NONE)
2228 Assert(stmt->larg == NULL && stmt->rarg == NULL);
2233 Assert(stmt->larg != NULL && stmt->rarg != NULL);
2234 if (stmt->sortClause || stmt->limitOffset || stmt->limitCount ||
2243 /* Process leaf SELECT */
2246 char selectName[32];
2251 * Transform SelectStmt into a Query.
2253 * Note: previously transformed sub-queries don't affect the parsing
2254 * of this sub-query, because they are not in the toplevel
2255 * pstate's namespace list.
2257 selectList = parse_analyze((Node *) stmt, pstate);
2259 Assert(length(selectList) == 1);
2260 selectQuery = (Query *) lfirst(selectList);
2263 * Make the leaf query be a subquery in the top-level rangetable.
2265 sprintf(selectName, "*SELECT* %d", length(pstate->p_rtable) + 1);
2266 rte = addRangeTableEntryForSubquery(pstate,
2268 makeAttr(pstrdup(selectName),
2273 * Return a RangeTblRef to replace the SelectStmt in the set-op
2276 rtr = makeNode(RangeTblRef);
2277 /* assume new rte is at end */
2278 rtr->rtindex = length(pstate->p_rtable);
2279 Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
2280 return (Node *) rtr;
2284 /* Process an internal node (set operation node) */
2285 SetOperationStmt *op = makeNode(SetOperationStmt);
2288 const char *context;
2290 context = (stmt->op == SETOP_UNION ? "UNION" :
2291 (stmt->op == SETOP_INTERSECT ? "INTERSECT" :
2295 op->all = stmt->all;
2298 * Recursively transform the child nodes.
2300 op->larg = transformSetOperationTree(pstate, stmt->larg);
2301 op->rarg = transformSetOperationTree(pstate, stmt->rarg);
2304 * Verify that the two children have the same number of non-junk
2305 * columns, and determine the types of the merged output columns.
2307 lcoltypes = getSetColTypes(pstate, op->larg);
2308 rcoltypes = getSetColTypes(pstate, op->rarg);
2309 if (length(lcoltypes) != length(rcoltypes))
2310 elog(ERROR, "Each %s query must have the same number of columns",
2313 while (lcoltypes != NIL)
2315 Oid lcoltype = (Oid) lfirsti(lcoltypes);
2316 Oid rcoltype = (Oid) lfirsti(rcoltypes);
2319 rescoltype = select_common_type(makeListi2(lcoltype, rcoltype),
2321 op->colTypes = lappendi(op->colTypes, rescoltype);
2322 lcoltypes = lnext(lcoltypes);
2323 rcoltypes = lnext(rcoltypes);
2332 * Get output column types of an (already transformed) set-op node
2335 getSetColTypes(ParseState *pstate, Node *node)
2337 if (IsA(node, RangeTblRef))
2339 RangeTblRef *rtr = (RangeTblRef *) node;
2340 RangeTblEntry *rte = rt_fetch(rtr->rtindex, pstate->p_rtable);
2341 Query *selectQuery = rte->subquery;
2345 Assert(selectQuery != NULL);
2346 /* Get types of non-junk columns */
2347 foreach(tl, selectQuery->targetList)
2349 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2350 Resdom *resnode = tle->resdom;
2352 if (resnode->resjunk)
2354 result = lappendi(result, resnode->restype);
2358 else if (IsA(node, SetOperationStmt))
2360 SetOperationStmt *op = (SetOperationStmt *) node;
2362 /* Result already computed during transformation of node */
2363 Assert(op->colTypes != NIL);
2364 return op->colTypes;
2368 elog(ERROR, "getSetColTypes: unexpected node %d",
2369 (int) nodeTag(node));
2370 return NIL; /* keep compiler quiet */
2376 * transformUpdateStmt -
2377 * transforms an update statement
2381 transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
2383 Query *qry = makeNode(Query);
2385 List *origTargetList;
2388 qry->commandType = CMD_UPDATE;
2389 pstate->p_is_update = true;
2391 qry->resultRelation = setTargetTable(pstate, stmt->relname,
2392 interpretInhOption(stmt->inhOpt),
2396 * the FROM clause is non-standard SQL syntax. We used to be able to
2397 * do this with REPLACE in POSTQUEL so we keep the feature.
2399 transformFromClause(pstate, stmt->fromClause);
2401 qry->targetList = transformTargetList(pstate, stmt->targetList);
2403 qual = transformWhereClause(pstate, stmt->whereClause);
2405 qry->rtable = pstate->p_rtable;
2406 qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
2408 qry->hasSubLinks = pstate->p_hasSubLinks;
2409 qry->hasAggs = pstate->p_hasAggs;
2410 if (pstate->p_hasAggs)
2411 parseCheckAggregates(pstate, qry, qual);
2414 * Now we are done with SELECT-like processing, and can get on with
2415 * transforming the target list to match the UPDATE target columns.
2418 /* Prepare to assign non-conflicting resnos to resjunk attributes */
2419 if (pstate->p_last_resno <= pstate->p_target_relation->rd_rel->relnatts)
2420 pstate->p_last_resno = pstate->p_target_relation->rd_rel->relnatts + 1;
2422 /* Prepare non-junk columns for assignment to target table */
2423 origTargetList = stmt->targetList;
2424 foreach(tl, qry->targetList)
2426 TargetEntry *tle = (TargetEntry *) lfirst(tl);
2427 Resdom *resnode = tle->resdom;
2428 ResTarget *origTarget;
2430 if (resnode->resjunk)
2434 * Resjunk nodes need no additional processing, but be sure
2435 * they have names and resnos that do not match any target
2436 * columns; else rewriter or planner might get confused.
2438 resnode->resname = "?resjunk?";
2439 resnode->resno = (AttrNumber) pstate->p_last_resno++;
2442 if (origTargetList == NIL)
2443 elog(ERROR, "UPDATE target count mismatch --- internal error");
2444 origTarget = (ResTarget *) lfirst(origTargetList);
2445 updateTargetListEntry(pstate, tle, origTarget->name,
2446 attnameAttNum(pstate->p_target_relation,
2448 origTarget->indirection);
2449 origTargetList = lnext(origTargetList);
2451 if (origTargetList != NIL)
2452 elog(ERROR, "UPDATE target count mismatch --- internal error");
2458 * tranformAlterTableStmt -
2459 * transform an Alter Table Statement
2463 transformAlterTableStmt(ParseState *pstate, AlterTableStmt *stmt)
2467 qry = makeNode(Query);
2468 qry->commandType = CMD_UTILITY;
2471 * The only subtypes that currently have special handling are 'A'dd
2472 * column and Add 'C'onstraint. In addition, right now only Foreign
2473 * Key 'C'onstraints have a special transformation.
2476 switch (stmt->subtype)
2479 transformColumnType(pstate, (ColumnDef *) stmt->def);
2482 if (stmt->def && IsA(stmt->def, FkConstraint))
2484 CreateTrigStmt *fk_trigger;
2488 FkConstraint *fkconstraint;
2491 elog(NOTICE, "ALTER TABLE ... ADD CONSTRAINT will create implicit trigger(s) for FOREIGN KEY check(s)");
2493 fkconstraint = (FkConstraint *) stmt->def;
2496 * If the constraint has no name, set it to <unnamed>
2499 if (fkconstraint->constr_name == NULL)
2500 fkconstraint->constr_name = "<unnamed>";
2503 * If the attribute list for the referenced table was
2504 * omitted, lookup for the definition of the primary key
2507 if (fkconstraint->fk_attrs != NIL && fkconstraint->pk_attrs == NIL) {
2508 Oid pktypoid[INDEX_MAX_KEYS];
2509 transformFkeyGetPrimaryKey(fkconstraint, pktypoid);
2513 * Build a CREATE CONSTRAINT TRIGGER statement for the
2517 fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
2518 fk_trigger->trigname = fkconstraint->constr_name;
2519 fk_trigger->relname = stmt->relname;
2520 fk_trigger->funcname = "RI_FKey_check_ins";
2521 fk_trigger->before = false;
2522 fk_trigger->row = true;
2523 fk_trigger->actions[0] = 'i';
2524 fk_trigger->actions[1] = 'u';
2525 fk_trigger->actions[2] = '\0';
2526 fk_trigger->lang = NULL;
2527 fk_trigger->text = NULL;
2529 fk_trigger->attr = NIL;
2530 fk_trigger->when = NULL;
2531 fk_trigger->isconstraint = true;
2532 fk_trigger->deferrable = fkconstraint->deferrable;
2533 fk_trigger->initdeferred = fkconstraint->initdeferred;
2534 fk_trigger->constrrelname = fkconstraint->pktable_name;
2536 fk_trigger->args = NIL;
2537 fk_trigger->args = lappend(fk_trigger->args,
2538 makeString(fkconstraint->constr_name));
2539 fk_trigger->args = lappend(fk_trigger->args,
2540 makeString(stmt->relname));
2541 fk_trigger->args = lappend(fk_trigger->args,
2542 makeString(fkconstraint->pktable_name));
2543 fk_trigger->args = lappend(fk_trigger->args,
2544 makeString(fkconstraint->match_type));
2545 fk_attr = fkconstraint->fk_attrs;
2546 pk_attr = fkconstraint->pk_attrs;
2547 if (length(fk_attr) != length(pk_attr))
2549 elog(NOTICE, "Illegal FOREIGN KEY definition REFERENCES \"%s\"",
2550 fkconstraint->pktable_name);
2551 elog(ERROR, "number of key attributes in referenced table must be equal to foreign key");
2553 while (fk_attr != NIL)
2555 id = (Ident *) lfirst(fk_attr);
2556 fk_trigger->args = lappend(fk_trigger->args,
2557 makeString(id->name));
2559 id = (Ident *) lfirst(pk_attr);
2560 fk_trigger->args = lappend(fk_trigger->args,
2561 makeString(id->name));
2563 fk_attr = lnext(fk_attr);
2564 pk_attr = lnext(pk_attr);
2567 extras_after = lappend(extras_after, (Node *) fk_trigger);
2570 * Build a CREATE CONSTRAINT TRIGGER statement for the ON
2571 * DELETE action fired on the PK table !!!
2574 fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
2575 fk_trigger->trigname = fkconstraint->constr_name;
2576 fk_trigger->relname = fkconstraint->pktable_name;
2577 switch ((fkconstraint->actions & FKCONSTR_ON_DELETE_MASK)
2578 >> FKCONSTR_ON_DELETE_SHIFT)
2580 case FKCONSTR_ON_KEY_NOACTION:
2581 fk_trigger->funcname = "RI_FKey_noaction_del";
2583 case FKCONSTR_ON_KEY_RESTRICT:
2584 fk_trigger->funcname = "RI_FKey_restrict_del";
2586 case FKCONSTR_ON_KEY_CASCADE:
2587 fk_trigger->funcname = "RI_FKey_cascade_del";
2589 case FKCONSTR_ON_KEY_SETNULL:
2590 fk_trigger->funcname = "RI_FKey_setnull_del";
2592 case FKCONSTR_ON_KEY_SETDEFAULT:
2593 fk_trigger->funcname = "RI_FKey_setdefault_del";
2596 elog(ERROR, "Only one ON DELETE action can be specified for FOREIGN KEY constraint");
2599 fk_trigger->before = false;
2600 fk_trigger->row = true;
2601 fk_trigger->actions[0] = 'd';
2602 fk_trigger->actions[1] = '\0';
2603 fk_trigger->lang = NULL;
2604 fk_trigger->text = NULL;
2606 fk_trigger->attr = NIL;
2607 fk_trigger->when = NULL;
2608 fk_trigger->isconstraint = true;
2609 fk_trigger->deferrable = fkconstraint->deferrable;
2610 fk_trigger->initdeferred = fkconstraint->initdeferred;
2611 fk_trigger->constrrelname = stmt->relname;
2613 fk_trigger->args = NIL;
2614 fk_trigger->args = lappend(fk_trigger->args,
2615 makeString(fkconstraint->constr_name));
2616 fk_trigger->args = lappend(fk_trigger->args,
2617 makeString(stmt->relname));
2618 fk_trigger->args = lappend(fk_trigger->args,
2619 makeString(fkconstraint->pktable_name));
2620 fk_trigger->args = lappend(fk_trigger->args,
2621 makeString(fkconstraint->match_type));
2622 fk_attr = fkconstraint->fk_attrs;
2623 pk_attr = fkconstraint->pk_attrs;
2624 while (fk_attr != NIL)
2626 id = (Ident *) lfirst(fk_attr);
2627 fk_trigger->args = lappend(fk_trigger->args,
2628 makeString(id->name));
2630 id = (Ident *) lfirst(pk_attr);
2631 fk_trigger->args = lappend(fk_trigger->args,
2632 makeString(id->name));
2634 fk_attr = lnext(fk_attr);
2635 pk_attr = lnext(pk_attr);
2638 extras_after = lappend(extras_after, (Node *) fk_trigger);
2641 * Build a CREATE CONSTRAINT TRIGGER statement for the ON
2642 * UPDATE action fired on the PK table !!!
2645 fk_trigger = (CreateTrigStmt *) makeNode(CreateTrigStmt);
2646 fk_trigger->trigname = fkconstraint->constr_name;
2647 fk_trigger->relname = fkconstraint->pktable_name;
2648 switch ((fkconstraint->actions & FKCONSTR_ON_UPDATE_MASK)
2649 >> FKCONSTR_ON_UPDATE_SHIFT)
2651 case FKCONSTR_ON_KEY_NOACTION:
2652 fk_trigger->funcname = "RI_FKey_noaction_upd";
2654 case FKCONSTR_ON_KEY_RESTRICT:
2655 fk_trigger->funcname = "RI_FKey_restrict_upd";
2657 case FKCONSTR_ON_KEY_CASCADE:
2658 fk_trigger->funcname = "RI_FKey_cascade_upd";
2660 case FKCONSTR_ON_KEY_SETNULL:
2661 fk_trigger->funcname = "RI_FKey_setnull_upd";
2663 case FKCONSTR_ON_KEY_SETDEFAULT:
2664 fk_trigger->funcname = "RI_FKey_setdefault_upd";
2667 elog(ERROR, "Only one ON UPDATE action can be specified for FOREIGN KEY constraint");
2670 fk_trigger->before = false;
2671 fk_trigger->row = true;
2672 fk_trigger->actions[0] = 'u';
2673 fk_trigger->actions[1] = '\0';
2674 fk_trigger->lang = NULL;
2675 fk_trigger->text = NULL;
2677 fk_trigger->attr = NIL;
2678 fk_trigger->when = NULL;
2679 fk_trigger->isconstraint = true;
2680 fk_trigger->deferrable = fkconstraint->deferrable;
2681 fk_trigger->initdeferred = fkconstraint->initdeferred;
2682 fk_trigger->constrrelname = stmt->relname;
2684 fk_trigger->args = NIL;
2685 fk_trigger->args = lappend(fk_trigger->args,
2686 makeString(fkconstraint->constr_name));
2687 fk_trigger->args = lappend(fk_trigger->args,
2688 makeString(stmt->relname));
2689 fk_trigger->args = lappend(fk_trigger->args,
2690 makeString(fkconstraint->pktable_name));
2691 fk_trigger->args = lappend(fk_trigger->args,
2692 makeString(fkconstraint->match_type));
2693 fk_attr = fkconstraint->fk_attrs;
2694 pk_attr = fkconstraint->pk_attrs;
2695 while (fk_attr != NIL)
2697 id = (Ident *) lfirst(fk_attr);
2698 fk_trigger->args = lappend(fk_trigger->args,
2699 makeString(id->name));
2701 id = (Ident *) lfirst(pk_attr);
2702 fk_trigger->args = lappend(fk_trigger->args,
2703 makeString(id->name));
2705 fk_attr = lnext(fk_attr);
2706 pk_attr = lnext(pk_attr);
2709 extras_after = lappend(extras_after, (Node *) fk_trigger);
2715 qry->utilityStmt = (Node *) stmt;
2720 * Transform uses of %TYPE in a statement.
2723 transformTypeRefs(ParseState *pstate, Node *stmt)
2725 switch (nodeTag(stmt))
2727 case T_ProcedureStmt:
2729 ProcedureStmt *ps = (ProcedureStmt *) stmt;
2731 transformTypeRefsList(pstate, ps->argTypes);
2732 transformTypeRef(pstate, (TypeName *) ps->returnType);
2733 transformTypeRefsList(pstate, ps->withClause);
2739 CommentStmt *cs = (CommentStmt *) stmt;
2741 transformTypeRefsList(pstate, cs->objlist);
2745 case T_RemoveFuncStmt:
2747 RemoveFuncStmt *rs = (RemoveFuncStmt *) stmt;
2749 transformTypeRefsList(pstate, rs->args);
2755 DefineStmt *ds = (DefineStmt *) stmt;
2758 foreach(ele, ds->definition)
2760 DefElem *de = (DefElem *) lfirst(ele);
2763 && IsA(de->arg, TypeName))
2765 transformTypeRef(pstate, (TypeName *) de->arg);
2772 elog(ERROR, "Unsupported type %d in transformTypeRefs",
2781 * Transform uses of %TYPE in a list.
2784 transformTypeRefsList(ParseState *pstate, List *l)
2790 if (IsA(lfirst(ele), TypeName))
2791 transformTypeRef(pstate, (TypeName *) lfirst(ele));
2796 * Transform a TypeName to not use %TYPE.
2799 transformTypeRef(ParseState *pstate, TypeName *tn)
2806 if (tn->attrname == NULL)
2808 att = makeAttr(tn->name, tn->attrname);
2809 n = transformExpr(pstate, (Node *) att, EXPR_COLUMN_FIRST);
2811 elog(ERROR, "unsupported expression in %%TYPE");
2813 tyn = typeidTypeName(v->vartype);
2814 elog(NOTICE, "%s.%s%%TYPE converted to %s", tn->name, tn->attrname, tyn);
2816 tn->typmod = v->vartypmod;
2817 tn->attrname = NULL;
2820 /* exported so planner can check again after rewriting, query pullup, etc */
2822 CheckSelectForUpdate(Query *qry)
2824 if (qry->setOperations)
2825 elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
2826 if (qry->distinctClause != NIL)
2827 elog(ERROR, "SELECT FOR UPDATE is not allowed with DISTINCT clause");
2828 if (qry->groupClause != NIL)
2829 elog(ERROR, "SELECT FOR UPDATE is not allowed with GROUP BY clause");
2831 elog(ERROR, "SELECT FOR UPDATE is not allowed with AGGREGATE");
2835 transformForUpdate(Query *qry, List *forUpdate)
2837 List *rowMarks = qry->rowMarks;
2842 CheckSelectForUpdate(qry);
2844 if (lfirst(forUpdate) == NULL)
2846 /* all tables used in query */
2848 foreach(rt, qry->rtable)
2850 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2855 /* FOR UPDATE of subquery is propagated to subquery's rels */
2856 transformForUpdate(rte->subquery, makeList1(NULL));
2860 if (!intMember(i, rowMarks)) /* avoid duplicates */
2861 rowMarks = lappendi(rowMarks, i);
2862 rte->checkForWrite = true;
2868 /* just the named tables */
2869 foreach(l, forUpdate)
2871 char *relname = strVal(lfirst(l));
2874 foreach(rt, qry->rtable)
2876 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2879 if (strcmp(rte->eref->relname, relname) == 0)
2883 /* propagate to subquery */
2884 transformForUpdate(rte->subquery, makeList1(NULL));
2888 if (!intMember(i, rowMarks)) /* avoid duplicates */
2889 rowMarks = lappendi(rowMarks, i);
2890 rte->checkForWrite = true;
2896 elog(ERROR, "FOR UPDATE: relation \"%s\" not found in FROM clause",
2901 qry->rowMarks = rowMarks;
2906 * transformFkeyCheckAttrs -
2908 * Try to make sure that the attributes of a referenced table
2909 * belong to a unique (or primary key) constraint.
2913 transformFkeyCheckAttrs(FkConstraint *fkconstraint, Oid *pktypoid)
2916 Form_pg_attribute *pkrel_attrs;
2923 * Open the referenced table and get the attributes list
2925 pkrel = heap_openr(fkconstraint->pktable_name, AccessShareLock);
2927 elog(ERROR, "referenced table \"%s\" not found",
2928 fkconstraint->pktable_name);
2929 pkrel_attrs = pkrel->rd_att->attrs;
2932 * Get the list of index OIDs for the table from the relcache, and
2933 * look up each one in the pg_index syscache for each unique one, and
2934 * then compare the attributes we were given to those defined.
2936 indexoidlist = RelationGetIndexList(pkrel);
2938 foreach(indexoidscan, indexoidlist)
2940 Oid indexoid = lfirsti(indexoidscan);
2941 HeapTuple indexTuple;
2942 Form_pg_index indexStruct;
2944 indexTuple = SearchSysCache(INDEXRELID,
2945 ObjectIdGetDatum(indexoid),
2947 if (!HeapTupleIsValid(indexTuple))
2948 elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
2950 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
2952 if (indexStruct->indisunique)
2957 for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++);
2958 if (i != length(fkconstraint->pk_attrs))
2962 /* go through the fkconstraint->pk_attrs list */
2963 foreach(attrl, fkconstraint->pk_attrs)
2965 Ident *attr = lfirst(attrl);
2968 for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
2970 int pkattno = indexStruct->indkey[i];
2974 char *name = NameStr(pkrel_attrs[pkattno - 1]->attname);
2976 if (strcmp(name, attr->name) == 0)
2978 pktypoid[attnum++]=pkrel_attrs[pkattno-1]->atttypid;
2989 ReleaseSysCache(indexTuple);
2994 elog(ERROR, "UNIQUE constraint matching given keys for referenced table \"%s\" not found",
2995 fkconstraint->pktable_name);
2997 freeList(indexoidlist);
2998 heap_close(pkrel, AccessShareLock);
3003 * transformFkeyGetPrimaryKey -
3005 * Try to find the primary key attributes of a referenced table if
3006 * the column list in the REFERENCES specification was omitted.
3010 transformFkeyGetPrimaryKey(FkConstraint *fkconstraint, Oid *pktypoid)
3013 Form_pg_attribute *pkrel_attrs;
3016 HeapTuple indexTuple = NULL;
3017 Form_pg_index indexStruct = NULL;
3022 * Open the referenced table and get the attributes list
3024 pkrel = heap_openr(fkconstraint->pktable_name, AccessShareLock);
3026 elog(ERROR, "referenced table \"%s\" not found",
3027 fkconstraint->pktable_name);
3028 pkrel_attrs = pkrel->rd_att->attrs;
3031 * Get the list of index OIDs for the table from the relcache, and
3032 * look up each one in the pg_index syscache until we find one marked
3033 * primary key (hopefully there isn't more than one such).
3035 indexoidlist = RelationGetIndexList(pkrel);
3037 foreach(indexoidscan, indexoidlist)
3039 Oid indexoid = lfirsti(indexoidscan);
3041 indexTuple = SearchSysCache(INDEXRELID,
3042 ObjectIdGetDatum(indexoid),
3044 if (!HeapTupleIsValid(indexTuple))
3045 elog(ERROR, "transformFkeyGetPrimaryKey: index %u not found",
3047 indexStruct = (Form_pg_index) GETSTRUCT(indexTuple);
3048 if (indexStruct->indisprimary)
3050 ReleaseSysCache(indexTuple);
3054 freeList(indexoidlist);
3057 * Check that we found it
3059 if (indexStruct == NULL)
3060 elog(ERROR, "PRIMARY KEY for referenced table \"%s\" not found",
3061 fkconstraint->pktable_name);
3064 * Now build the list of PK attributes from the indkey definition
3065 * using the attribute names of the PK relation descriptor
3067 for (i = 0; i < INDEX_MAX_KEYS && indexStruct->indkey[i] != 0; i++)
3069 int pkattno = indexStruct->indkey[i];
3070 Ident *pkattr = makeNode(Ident);
3072 pkattr->name = DatumGetCString(DirectFunctionCall1(nameout,
3073 NameGetDatum(&(pkrel_attrs[pkattno - 1]->attname))));
3074 pkattr->indirection = NIL;
3075 pkattr->isRel = false;
3076 pktypoid[attnum++]=pkrel_attrs[pkattno-1]->atttypid;
3078 fkconstraint->pk_attrs = lappend(fkconstraint->pk_attrs, pkattr);
3081 ReleaseSysCache(indexTuple);
3083 heap_close(pkrel, AccessShareLock);
3087 * Preprocess a list of column constraint clauses
3088 * to attach constraint attributes to their primary constraint nodes
3089 * and detect inconsistent/misplaced constraint attributes.
3091 * NOTE: currently, attributes are only supported for FOREIGN KEY primary
3092 * constraints, but someday they ought to be supported for other constraints.
3095 transformConstraintAttrs(List *constraintList)
3097 Node *lastprimarynode = NULL;
3098 bool saw_deferrability = false;
3099 bool saw_initially = false;
3102 foreach(clist, constraintList)
3104 Node *node = lfirst(clist);
3106 if (!IsA(node, Constraint))
3108 lastprimarynode = node;
3109 /* reset flags for new primary node */
3110 saw_deferrability = false;
3111 saw_initially = false;
3115 Constraint *con = (Constraint *) node;
3117 switch (con->contype)
3119 case CONSTR_ATTR_DEFERRABLE:
3120 if (lastprimarynode == NULL ||
3121 !IsA(lastprimarynode, FkConstraint))
3122 elog(ERROR, "Misplaced DEFERRABLE clause");
3123 if (saw_deferrability)
3124 elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed");
3125 saw_deferrability = true;
3126 ((FkConstraint *) lastprimarynode)->deferrable = true;
3128 case CONSTR_ATTR_NOT_DEFERRABLE:
3129 if (lastprimarynode == NULL ||
3130 !IsA(lastprimarynode, FkConstraint))
3131 elog(ERROR, "Misplaced NOT DEFERRABLE clause");
3132 if (saw_deferrability)
3133 elog(ERROR, "Multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed");
3134 saw_deferrability = true;
3135 ((FkConstraint *) lastprimarynode)->deferrable = false;
3136 if (saw_initially &&
3137 ((FkConstraint *) lastprimarynode)->initdeferred)
3138 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
3140 case CONSTR_ATTR_DEFERRED:
3141 if (lastprimarynode == NULL ||
3142 !IsA(lastprimarynode, FkConstraint))
3143 elog(ERROR, "Misplaced INITIALLY DEFERRED clause");
3145 elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed");
3146 saw_initially = true;
3147 ((FkConstraint *) lastprimarynode)->initdeferred = true;
3150 * If only INITIALLY DEFERRED appears, assume
3153 if (!saw_deferrability)
3154 ((FkConstraint *) lastprimarynode)->deferrable = true;
3155 else if (!((FkConstraint *) lastprimarynode)->deferrable)
3156 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
3158 case CONSTR_ATTR_IMMEDIATE:
3159 if (lastprimarynode == NULL ||
3160 !IsA(lastprimarynode, FkConstraint))
3161 elog(ERROR, "Misplaced INITIALLY IMMEDIATE clause");
3163 elog(ERROR, "Multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed");
3164 saw_initially = true;
3165 ((FkConstraint *) lastprimarynode)->initdeferred = false;
3168 /* Otherwise it's not an attribute */
3169 lastprimarynode = node;
3170 /* reset flags for new primary node */
3171 saw_deferrability = false;
3172 saw_initially = false;
3179 /* Build a FromExpr node */
3181 makeFromExpr(List *fromlist, Node *quals)
3183 FromExpr *f = makeNode(FromExpr);
3185 f->fromlist = fromlist;
3191 * Special handling of type definition for a column
3194 transformColumnType(ParseState *pstate, ColumnDef *column)
3196 TypeName *typename = column->typename;
3197 Type ctype = typenameType(typename->name);
3200 * If the column doesn't have an explicitly specified typmod, check to
3201 * see if we want to insert a default length.
3203 * Note that we deliberately do NOT look at array or set information
3204 * here; "numeric[]" needs the same default typmod as "numeric".
3206 if (typename->typmod == -1)
3208 switch (typeTypeId(ctype))
3211 /* "char" -> "char(1)" */
3212 typename->typmod = VARHDRSZ + 1;
3215 typename->typmod = VARHDRSZ +
3216 ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE);
3219 /* 'bit' -> 'bit(1)' */
3220 typename->typmod = 1;
3226 * Is this the name of a complex type? If so, implement it as a set.
3228 * XXX this is a hangover from ancient Berkeley code that probably
3229 * doesn't work anymore anyway.
3231 if (typeTypeRelid(ctype) != InvalidOid)
3235 * (Eventually add in here that the set can only contain one
3238 typename->setof = true;
3241 ReleaseSysCache(ctype);