]> granicus.if.org Git - postgresql/blob - src/backend/parser/parse_utilcmd.c
Add exclusion constraints, which generalize the concept of uniqueness to
[postgresql] / src / backend / parser / parse_utilcmd.c
1 /*-------------------------------------------------------------------------
2  *
3  * parse_utilcmd.c
4  *        Perform parse analysis work for various utility commands
5  *
6  * Formerly we did this work during parse_analyze() in analyze.c.  However
7  * that is fairly unsafe in the presence of querytree caching, since any
8  * database state that we depend on in making the transformations might be
9  * obsolete by the time the utility command is executed; and utility commands
10  * have no infrastructure for holding locks or rechecking plan validity.
11  * Hence these functions are now called at the start of execution of their
12  * respective utility commands.
13  *
14  * NOTE: in general we must avoid scribbling on the passed-in raw parse
15  * tree, since it might be in a plan cache.  The simplest solution is
16  * a quick copyObject() call before manipulating the query tree.
17  *
18  *
19  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
20  * Portions Copyright (c) 1994, Regents of the University of California
21  *
22  *      $PostgreSQL: pgsql/src/backend/parser/parse_utilcmd.c,v 2.31 2009/12/07 05:22:22 tgl Exp $
23  *
24  *-------------------------------------------------------------------------
25  */
26
27 #include "postgres.h"
28
29 #include "access/genam.h"
30 #include "access/heapam.h"
31 #include "access/reloptions.h"
32 #include "catalog/dependency.h"
33 #include "catalog/heap.h"
34 #include "catalog/index.h"
35 #include "catalog/namespace.h"
36 #include "catalog/pg_constraint.h"
37 #include "catalog/pg_opclass.h"
38 #include "catalog/pg_operator.h"
39 #include "catalog/pg_type.h"
40 #include "commands/comment.h"
41 #include "commands/defrem.h"
42 #include "commands/tablecmds.h"
43 #include "commands/tablespace.h"
44 #include "miscadmin.h"
45 #include "nodes/makefuncs.h"
46 #include "nodes/nodeFuncs.h"
47 #include "parser/analyze.h"
48 #include "parser/parse_clause.h"
49 #include "parser/parse_expr.h"
50 #include "parser/parse_relation.h"
51 #include "parser/parse_type.h"
52 #include "parser/parse_utilcmd.h"
53 #include "parser/parser.h"
54 #include "rewrite/rewriteManip.h"
55 #include "utils/acl.h"
56 #include "utils/builtins.h"
57 #include "utils/lsyscache.h"
58 #include "utils/relcache.h"
59 #include "utils/syscache.h"
60
61
62 /* State shared by transformCreateStmt and its subroutines */
63 typedef struct
64 {
65         const char *stmtType;           /* "CREATE TABLE" or "ALTER TABLE" */
66         RangeVar   *relation;           /* relation to create */
67         Relation        rel;                    /* opened/locked rel, if ALTER */
68         List       *inhRelations;       /* relations to inherit from */
69         bool            isalter;                /* true if altering existing table */
70         bool            hasoids;                /* does relation have an OID column? */
71         List       *columns;            /* ColumnDef items */
72         List       *ckconstraints;      /* CHECK constraints */
73         List       *fkconstraints;      /* FOREIGN KEY constraints */
74         List       *ixconstraints;      /* index-creating constraints */
75         List       *inh_indexes;        /* cloned indexes from INCLUDING INDEXES */
76         List       *blist;                      /* "before list" of things to do before
77                                                                  * creating the table */
78         List       *alist;                      /* "after list" of things to do after creating
79                                                                  * the table */
80         IndexStmt  *pkey;                       /* PRIMARY KEY index, if any */
81 } CreateStmtContext;
82
83 /* State shared by transformCreateSchemaStmt and its subroutines */
84 typedef struct
85 {
86         const char *stmtType;           /* "CREATE SCHEMA" or "ALTER SCHEMA" */
87         char       *schemaname;         /* name of schema */
88         char       *authid;                     /* owner of schema */
89         List       *sequences;          /* CREATE SEQUENCE items */
90         List       *tables;                     /* CREATE TABLE items */
91         List       *views;                      /* CREATE VIEW items */
92         List       *indexes;            /* CREATE INDEX items */
93         List       *triggers;           /* CREATE TRIGGER items */
94         List       *grants;                     /* GRANT items */
95 } CreateSchemaStmtContext;
96
97
98 static void transformColumnDefinition(ParseState *pstate,
99                                                   CreateStmtContext *cxt,
100                                                   ColumnDef *column);
101 static void transformTableConstraint(ParseState *pstate,
102                                                  CreateStmtContext *cxt,
103                                                  Constraint *constraint);
104 static void transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
105                                          InhRelation *inhrelation);
106 static char *chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt);
107 static IndexStmt *generateClonedIndexStmt(CreateStmtContext *cxt,
108                                                 Relation parent_index, AttrNumber *attmap);
109 static List *get_opclass(Oid opclass, Oid actual_datatype);
110 static void transformIndexConstraints(ParseState *pstate,
111                                                   CreateStmtContext *cxt);
112 static IndexStmt *transformIndexConstraint(Constraint *constraint,
113                                                  CreateStmtContext *cxt);
114 static void transformFKConstraints(ParseState *pstate,
115                                            CreateStmtContext *cxt,
116                                            bool skipValidation,
117                                            bool isAddConstraint);
118 static void transformConstraintAttrs(ParseState *pstate, List *constraintList);
119 static void transformColumnType(ParseState *pstate, ColumnDef *column);
120 static void setSchemaName(char *context_schema, char **stmt_schema_name);
121
122
123 /*
124  * transformCreateStmt -
125  *        parse analysis for CREATE TABLE
126  *
127  * Returns a List of utility commands to be done in sequence.  One of these
128  * will be the transformed CreateStmt, but there may be additional actions
129  * to be done before and after the actual DefineRelation() call.
130  *
131  * SQL92 allows constraints to be scattered all over, so thumb through
132  * the columns and collect all constraints into one place.
133  * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
134  * then expand those into multiple IndexStmt blocks.
135  *        - thomas 1997-12-02
136  */
137 List *
138 transformCreateStmt(CreateStmt *stmt, const char *queryString)
139 {
140         ParseState *pstate;
141         CreateStmtContext cxt;
142         List       *result;
143         List       *save_alist;
144         ListCell   *elements;
145
146         /*
147          * We must not scribble on the passed-in CreateStmt, so copy it.  (This is
148          * overkill, but easy.)
149          */
150         stmt = (CreateStmt *) copyObject(stmt);
151
152         /*
153          * If the target relation name isn't schema-qualified, make it so.  This
154          * prevents some corner cases in which added-on rewritten commands might
155          * think they should apply to other relations that have the same name and
156          * are earlier in the search path.      "istemp" is equivalent to a
157          * specification of pg_temp, so no need for anything extra in that case.
158          */
159         if (stmt->relation->schemaname == NULL && !stmt->relation->istemp)
160         {
161                 Oid                     namespaceid = RangeVarGetCreationNamespace(stmt->relation);
162
163                 stmt->relation->schemaname = get_namespace_name(namespaceid);
164         }
165
166         /* Set up pstate */
167         pstate = make_parsestate(NULL);
168         pstate->p_sourcetext = queryString;
169
170         cxt.stmtType = "CREATE TABLE";
171         cxt.relation = stmt->relation;
172         cxt.rel = NULL;
173         cxt.inhRelations = stmt->inhRelations;
174         cxt.isalter = false;
175         cxt.columns = NIL;
176         cxt.ckconstraints = NIL;
177         cxt.fkconstraints = NIL;
178         cxt.ixconstraints = NIL;
179         cxt.inh_indexes = NIL;
180         cxt.blist = NIL;
181         cxt.alist = NIL;
182         cxt.pkey = NULL;
183         cxt.hasoids = interpretOidsOption(stmt->options);
184
185         /*
186          * Run through each primary element in the table creation clause. Separate
187          * column defs from constraints, and do preliminary analysis.
188          */
189         foreach(elements, stmt->tableElts)
190         {
191                 Node       *element = lfirst(elements);
192
193                 switch (nodeTag(element))
194                 {
195                         case T_ColumnDef:
196                                 transformColumnDefinition(pstate, &cxt,
197                                                                                   (ColumnDef *) element);
198                                 break;
199
200                         case T_Constraint:
201                                 transformTableConstraint(pstate, &cxt,
202                                                                                  (Constraint *) element);
203                                 break;
204
205                         case T_InhRelation:
206                                 transformInhRelation(pstate, &cxt,
207                                                                          (InhRelation *) element);
208                                 break;
209
210                         default:
211                                 elog(ERROR, "unrecognized node type: %d",
212                                          (int) nodeTag(element));
213                                 break;
214                 }
215         }
216
217         /*
218          * transformIndexConstraints wants cxt.alist to contain only index
219          * statements, so transfer anything we already have into save_alist.
220          */
221         save_alist = cxt.alist;
222         cxt.alist = NIL;
223
224         Assert(stmt->constraints == NIL);
225
226         /*
227          * Postprocess constraints that give rise to index definitions.
228          */
229         transformIndexConstraints(pstate, &cxt);
230
231         /*
232          * Postprocess foreign-key constraints.
233          */
234         transformFKConstraints(pstate, &cxt, true, false);
235
236         /*
237          * Output results.
238          */
239         stmt->tableElts = cxt.columns;
240         stmt->constraints = cxt.ckconstraints;
241
242         result = lappend(cxt.blist, stmt);
243         result = list_concat(result, cxt.alist);
244         result = list_concat(result, save_alist);
245
246         return result;
247 }
248
249 /*
250  * transformColumnDefinition -
251  *              transform a single ColumnDef within CREATE TABLE
252  *              Also used in ALTER TABLE ADD COLUMN
253  */
254 static void
255 transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
256                                                   ColumnDef *column)
257 {
258         bool            is_serial;
259         bool            saw_nullable;
260         bool            saw_default;
261         Constraint *constraint;
262         ListCell   *clist;
263
264         cxt->columns = lappend(cxt->columns, column);
265
266         /* Check for SERIAL pseudo-types */
267         is_serial = false;
268         if (list_length(column->typeName->names) == 1 &&
269                 !column->typeName->pct_type)
270         {
271                 char       *typname = strVal(linitial(column->typeName->names));
272
273                 if (strcmp(typname, "serial") == 0 ||
274                         strcmp(typname, "serial4") == 0)
275                 {
276                         is_serial = true;
277                         column->typeName->names = NIL;
278                         column->typeName->typeOid = INT4OID;
279                 }
280                 else if (strcmp(typname, "bigserial") == 0 ||
281                                  strcmp(typname, "serial8") == 0)
282                 {
283                         is_serial = true;
284                         column->typeName->names = NIL;
285                         column->typeName->typeOid = INT8OID;
286                 }
287
288                 /*
289                  * We have to reject "serial[]" explicitly, because once we've set
290                  * typeid, LookupTypeName won't notice arrayBounds.  We don't need any
291                  * special coding for serial(typmod) though.
292                  */
293                 if (is_serial && column->typeName->arrayBounds != NIL)
294                         ereport(ERROR,
295                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
296                                          errmsg("array of serial is not implemented"),
297                                          parser_errposition(pstate, column->typeName->location)));
298         }
299
300         /* Do necessary work on the column type declaration */
301         transformColumnType(pstate, column);
302
303         /* Special actions for SERIAL pseudo-types */
304         if (is_serial)
305         {
306                 Oid                     snamespaceid;
307                 char       *snamespace;
308                 char       *sname;
309                 char       *qstring;
310                 A_Const    *snamenode;
311                 TypeCast   *castnode;
312                 FuncCall   *funccallnode;
313                 CreateSeqStmt *seqstmt;
314                 AlterSeqStmt *altseqstmt;
315                 List       *attnamelist;
316
317                 /*
318                  * Determine namespace and name to use for the sequence.
319                  *
320                  * Although we use ChooseRelationName, it's not guaranteed that the
321                  * selected sequence name won't conflict; given sufficiently long
322                  * field names, two different serial columns in the same table could
323                  * be assigned the same sequence name, and we'd not notice since we
324                  * aren't creating the sequence quite yet.  In practice this seems
325                  * quite unlikely to be a problem, especially since few people would
326                  * need two serial columns in one table.
327                  */
328                 if (cxt->rel)
329                         snamespaceid = RelationGetNamespace(cxt->rel);
330                 else
331                         snamespaceid = RangeVarGetCreationNamespace(cxt->relation);
332                 snamespace = get_namespace_name(snamespaceid);
333                 sname = ChooseRelationName(cxt->relation->relname,
334                                                                    column->colname,
335                                                                    "seq",
336                                                                    snamespaceid);
337
338                 ereport(NOTICE,
339                                 (errmsg("%s will create implicit sequence \"%s\" for serial column \"%s.%s\"",
340                                                 cxt->stmtType, sname,
341                                                 cxt->relation->relname, column->colname)));
342
343                 /*
344                  * Build a CREATE SEQUENCE command to create the sequence object, and
345                  * add it to the list of things to be done before this CREATE/ALTER
346                  * TABLE.
347                  */
348                 seqstmt = makeNode(CreateSeqStmt);
349                 seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
350                 seqstmt->options = NIL;
351
352                 cxt->blist = lappend(cxt->blist, seqstmt);
353
354                 /*
355                  * Build an ALTER SEQUENCE ... OWNED BY command to mark the sequence
356                  * as owned by this column, and add it to the list of things to be
357                  * done after this CREATE/ALTER TABLE.
358                  */
359                 altseqstmt = makeNode(AlterSeqStmt);
360                 altseqstmt->sequence = makeRangeVar(snamespace, sname, -1);
361                 attnamelist = list_make3(makeString(snamespace),
362                                                                  makeString(cxt->relation->relname),
363                                                                  makeString(column->colname));
364                 altseqstmt->options = list_make1(makeDefElem("owned_by",
365                                                                                                          (Node *) attnamelist));
366
367                 cxt->alist = lappend(cxt->alist, altseqstmt);
368
369                 /*
370                  * Create appropriate constraints for SERIAL.  We do this in full,
371                  * rather than shortcutting, so that we will detect any conflicting
372                  * constraints the user wrote (like a different DEFAULT).
373                  *
374                  * Create an expression tree representing the function call
375                  * nextval('sequencename').  We cannot reduce the raw tree to cooked
376                  * form until after the sequence is created, but there's no need to do
377                  * so.
378                  */
379                 qstring = quote_qualified_identifier(snamespace, sname);
380                 snamenode = makeNode(A_Const);
381                 snamenode->val.type = T_String;
382                 snamenode->val.val.str = qstring;
383                 snamenode->location = -1;
384                 castnode = makeNode(TypeCast);
385                 castnode->typeName = SystemTypeName("regclass");
386                 castnode->arg = (Node *) snamenode;
387                 castnode->location = -1;
388                 funccallnode = makeNode(FuncCall);
389                 funccallnode->funcname = SystemFuncName("nextval");
390                 funccallnode->args = list_make1(castnode);
391                 funccallnode->agg_star = false;
392                 funccallnode->agg_distinct = false;
393                 funccallnode->func_variadic = false;
394                 funccallnode->over = NULL;
395                 funccallnode->location = -1;
396
397                 constraint = makeNode(Constraint);
398                 constraint->contype = CONSTR_DEFAULT;
399                 constraint->location = -1;
400                 constraint->raw_expr = (Node *) funccallnode;
401                 constraint->cooked_expr = NULL;
402                 column->constraints = lappend(column->constraints, constraint);
403
404                 constraint = makeNode(Constraint);
405                 constraint->contype = CONSTR_NOTNULL;
406                 constraint->location = -1;
407                 column->constraints = lappend(column->constraints, constraint);
408         }
409
410         /* Process column constraints, if any... */
411         transformConstraintAttrs(pstate, column->constraints);
412
413         saw_nullable = false;
414         saw_default = false;
415
416         foreach(clist, column->constraints)
417         {
418                 constraint = lfirst(clist);
419                 Assert(IsA(constraint, Constraint));
420
421                 switch (constraint->contype)
422                 {
423                         case CONSTR_NULL:
424                                 if (saw_nullable && column->is_not_null)
425                                         ereport(ERROR,
426                                                         (errcode(ERRCODE_SYNTAX_ERROR),
427                                                          errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
428                                                                         column->colname, cxt->relation->relname),
429                                                          parser_errposition(pstate,
430                                                                                                 constraint->location)));
431                                 column->is_not_null = FALSE;
432                                 saw_nullable = true;
433                                 break;
434
435                         case CONSTR_NOTNULL:
436                                 if (saw_nullable && !column->is_not_null)
437                                         ereport(ERROR,
438                                                         (errcode(ERRCODE_SYNTAX_ERROR),
439                                                          errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
440                                                                         column->colname, cxt->relation->relname),
441                                                          parser_errposition(pstate,
442                                                                                                 constraint->location)));
443                                 column->is_not_null = TRUE;
444                                 saw_nullable = true;
445                                 break;
446
447                         case CONSTR_DEFAULT:
448                                 if (saw_default)
449                                         ereport(ERROR,
450                                                         (errcode(ERRCODE_SYNTAX_ERROR),
451                                                          errmsg("multiple default values specified for column \"%s\" of table \"%s\"",
452                                                                         column->colname, cxt->relation->relname),
453                                                          parser_errposition(pstate,
454                                                                                                 constraint->location)));
455                                 column->raw_default = constraint->raw_expr;
456                                 Assert(constraint->cooked_expr == NULL);
457                                 saw_default = true;
458                                 break;
459
460                         case CONSTR_CHECK:
461                                 cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
462                                 break;
463
464                         case CONSTR_PRIMARY:
465                         case CONSTR_UNIQUE:
466                                 if (constraint->keys == NIL)
467                                         constraint->keys = list_make1(makeString(column->colname));
468                                 cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
469                                 break;
470
471                         case CONSTR_EXCLUSION:
472                                 /* grammar does not allow EXCLUDE as a column constraint */
473                                 elog(ERROR, "column exclusion constraints are not supported");
474                                 break;
475
476                         case CONSTR_FOREIGN:
477                                 /*
478                                  * Fill in the current attribute's name and throw it into the
479                                  * list of FK constraints to be processed later.
480                                  */
481                                 constraint->fk_attrs = list_make1(makeString(column->colname));
482                                 cxt->fkconstraints = lappend(cxt->fkconstraints, constraint);
483                                 break;
484
485                         case CONSTR_ATTR_DEFERRABLE:
486                         case CONSTR_ATTR_NOT_DEFERRABLE:
487                         case CONSTR_ATTR_DEFERRED:
488                         case CONSTR_ATTR_IMMEDIATE:
489                                 /* transformConstraintAttrs took care of these */
490                                 break;
491
492                         default:
493                                 elog(ERROR, "unrecognized constraint type: %d",
494                                          constraint->contype);
495                                 break;
496                 }
497         }
498 }
499
500 /*
501  * transformTableConstraint
502  *              transform a Constraint node within CREATE TABLE or ALTER TABLE
503  */
504 static void
505 transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
506                                                  Constraint *constraint)
507 {
508         switch (constraint->contype)
509         {
510                 case CONSTR_PRIMARY:
511                 case CONSTR_UNIQUE:
512                 case CONSTR_EXCLUSION:
513                         cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
514                         break;
515
516                 case CONSTR_CHECK:
517                         cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
518                         break;
519
520                 case CONSTR_FOREIGN:
521                         cxt->fkconstraints = lappend(cxt->fkconstraints, constraint);
522                         break;
523
524                 case CONSTR_NULL:
525                 case CONSTR_NOTNULL:
526                 case CONSTR_DEFAULT:
527                 case CONSTR_ATTR_DEFERRABLE:
528                 case CONSTR_ATTR_NOT_DEFERRABLE:
529                 case CONSTR_ATTR_DEFERRED:
530                 case CONSTR_ATTR_IMMEDIATE:
531                         elog(ERROR, "invalid context for constraint type %d",
532                                  constraint->contype);
533                         break;
534
535                 default:
536                         elog(ERROR, "unrecognized constraint type: %d",
537                                  constraint->contype);
538                         break;
539         }
540 }
541
542 /*
543  * transformInhRelation
544  *
545  * Change the LIKE <subtable> portion of a CREATE TABLE statement into
546  * column definitions which recreate the user defined column portions of
547  * <subtable>.
548  */
549 static void
550 transformInhRelation(ParseState *pstate, CreateStmtContext *cxt,
551                                          InhRelation *inhRelation)
552 {
553         AttrNumber      parent_attno;
554         Relation        relation;
555         TupleDesc       tupleDesc;
556         TupleConstr *constr;
557         AclResult       aclresult;
558         char       *comment;
559
560         relation = parserOpenTable(pstate, inhRelation->relation, AccessShareLock);
561
562         if (relation->rd_rel->relkind != RELKIND_RELATION)
563                 ereport(ERROR,
564                                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
565                                  errmsg("inherited relation \"%s\" is not a table",
566                                                 inhRelation->relation->relname)));
567
568         /*
569          * Check for SELECT privilages
570          */
571         aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
572                                                                   ACL_SELECT);
573         if (aclresult != ACLCHECK_OK)
574                 aclcheck_error(aclresult, ACL_KIND_CLASS,
575                                            RelationGetRelationName(relation));
576
577         tupleDesc = RelationGetDescr(relation);
578         constr = tupleDesc->constr;
579
580         /*
581          * Insert the copied attributes into the cxt for the new table definition.
582          */
583         for (parent_attno = 1; parent_attno <= tupleDesc->natts;
584                  parent_attno++)
585         {
586                 Form_pg_attribute attribute = tupleDesc->attrs[parent_attno - 1];
587                 char       *attributeName = NameStr(attribute->attname);
588                 ColumnDef  *def;
589
590                 /*
591                  * Ignore dropped columns in the parent.
592                  */
593                 if (attribute->attisdropped)
594                         continue;
595
596                 /*
597                  * Create a new column, which is marked as NOT inherited.
598                  *
599                  * For constraints, ONLY the NOT NULL constraint is inherited by the
600                  * new column definition per SQL99.
601                  */
602                 def = makeNode(ColumnDef);
603                 def->colname = pstrdup(attributeName);
604                 def->typeName = makeTypeNameFromOid(attribute->atttypid,
605                                                                                         attribute->atttypmod);
606                 def->inhcount = 0;
607                 def->is_local = true;
608                 def->is_not_null = attribute->attnotnull;
609                 def->raw_default = NULL;
610                 def->cooked_default = NULL;
611                 def->constraints = NIL;
612
613                 /*
614                  * Add to column list
615                  */
616                 cxt->columns = lappend(cxt->columns, def);
617
618                 /*
619                  * Copy default, if present and the default has been requested
620                  */
621                 if (attribute->atthasdef &&
622                         (inhRelation->options & CREATE_TABLE_LIKE_DEFAULTS))
623                 {
624                         Node       *this_default = NULL;
625                         AttrDefault *attrdef;
626                         int                     i;
627
628                         /* Find default in constraint structure */
629                         Assert(constr != NULL);
630                         attrdef = constr->defval;
631                         for (i = 0; i < constr->num_defval; i++)
632                         {
633                                 if (attrdef[i].adnum == parent_attno)
634                                 {
635                                         this_default = stringToNode(attrdef[i].adbin);
636                                         break;
637                                 }
638                         }
639                         Assert(this_default != NULL);
640
641                         /*
642                          * If default expr could contain any vars, we'd need to fix 'em,
643                          * but it can't; so default is ready to apply to child.
644                          */
645
646                         def->cooked_default = this_default;
647                 }
648
649                 /* Likewise, copy storage if requested */
650                 if (inhRelation->options & CREATE_TABLE_LIKE_STORAGE)
651                         def->storage = attribute->attstorage;
652                 else
653                         def->storage = 0;
654
655                 /* Likewise, copy comment if requested */
656                 if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) &&
657                         (comment = GetComment(attribute->attrelid,
658                                                                   RelationRelationId,
659                                                                   attribute->attnum)) != NULL)
660                 {
661                         CommentStmt *stmt = makeNode(CommentStmt);
662
663                         stmt->objtype = OBJECT_COLUMN;
664                         stmt->objname = list_make3(makeString(cxt->relation->schemaname),
665                                                                            makeString(cxt->relation->relname),
666                                                                            makeString(def->colname));
667                         stmt->objargs = NIL;
668                         stmt->comment = comment;
669
670                         cxt->alist = lappend(cxt->alist, stmt);
671                 }
672         }
673
674         /*
675          * Copy CHECK constraints if requested, being careful to adjust attribute
676          * numbers
677          */
678         if ((inhRelation->options & CREATE_TABLE_LIKE_CONSTRAINTS) &&
679                 tupleDesc->constr)
680         {
681                 AttrNumber *attmap = varattnos_map_schema(tupleDesc, cxt->columns);
682                 int                     ccnum;
683
684                 for (ccnum = 0; ccnum < tupleDesc->constr->num_check; ccnum++)
685                 {
686                         char       *ccname = tupleDesc->constr->check[ccnum].ccname;
687                         char       *ccbin = tupleDesc->constr->check[ccnum].ccbin;
688                         Node       *ccbin_node = stringToNode(ccbin);
689                         Constraint *n = makeNode(Constraint);
690
691                         change_varattnos_of_a_node(ccbin_node, attmap);
692
693                         n->contype = CONSTR_CHECK;
694                         n->location = -1;
695                         n->conname = pstrdup(ccname);
696                         n->raw_expr = NULL;
697                         n->cooked_expr = nodeToString(ccbin_node);
698                         cxt->ckconstraints = lappend(cxt->ckconstraints, n);
699
700                         /* Copy comment on constraint */
701                         if ((inhRelation->options & CREATE_TABLE_LIKE_COMMENTS) &&
702                                 (comment = GetComment(GetConstraintByName(RelationGetRelid(relation),
703                                                                                                                   n->conname),
704                                                                           ConstraintRelationId,
705                                                                           0)) != NULL)
706                         {
707                                 CommentStmt *stmt = makeNode(CommentStmt);
708
709                                 stmt->objtype = OBJECT_CONSTRAINT;
710                                 stmt->objname = list_make3(makeString(cxt->relation->schemaname),
711                                                                                    makeString(cxt->relation->relname),
712                                                                                    makeString(n->conname));
713                                 stmt->objargs = NIL;
714                                 stmt->comment = comment;
715
716                                 cxt->alist = lappend(cxt->alist, stmt);
717                         }
718                 }
719         }
720
721         /*
722          * Likewise, copy indexes if requested
723          */
724         if ((inhRelation->options & CREATE_TABLE_LIKE_INDEXES) &&
725                 relation->rd_rel->relhasindex)
726         {
727                 AttrNumber *attmap = varattnos_map_schema(tupleDesc, cxt->columns);
728                 List       *parent_indexes;
729                 ListCell   *l;
730
731                 parent_indexes = RelationGetIndexList(relation);
732
733                 foreach(l, parent_indexes)
734                 {
735                         Oid                     parent_index_oid = lfirst_oid(l);
736                         Relation        parent_index;
737                         IndexStmt  *index_stmt;
738
739                         parent_index = index_open(parent_index_oid, AccessShareLock);
740
741                         /* Build CREATE INDEX statement to recreate the parent_index */
742                         index_stmt = generateClonedIndexStmt(cxt, parent_index, attmap);
743
744                         /* Copy comment on index */
745                         if (inhRelation->options & CREATE_TABLE_LIKE_COMMENTS)
746                         {
747                                 CommentStmt        *stmt;
748                                 ListCell           *lc;
749                                 int                             i;
750
751                                 comment = GetComment(parent_index_oid, RelationRelationId, 0);
752                                 
753                                 if (comment != NULL)
754                                 {
755                                         /* Assign name for index because CommentStmt requires name. */
756                                         if (index_stmt->idxname == NULL)
757                                                 index_stmt->idxname = chooseIndexName(cxt->relation, index_stmt);
758
759                                         stmt = makeNode(CommentStmt);
760                                         stmt->objtype = OBJECT_INDEX;
761                                         stmt->objname = list_make2(makeString(cxt->relation->schemaname),
762                                                                                            makeString(index_stmt->idxname));
763                                         stmt->objargs = NIL;
764                                         stmt->comment = comment;
765
766                                         cxt->alist = lappend(cxt->alist, stmt);
767                                 }
768
769                                 /* Copy comment on index's columns */
770                                 i = 0;
771                                 foreach(lc, index_stmt->indexParams)
772                                 {
773                                         char       *attname;
774
775                                         i++;
776                                         comment = GetComment(parent_index_oid, RelationRelationId, i);
777                                         if (comment == NULL)
778                                                 continue;
779
780                                         /* Assign name for index because CommentStmt requires name. */
781                                         if (index_stmt->idxname == NULL)
782                                                 index_stmt->idxname = chooseIndexName(cxt->relation, index_stmt);
783
784                                         attname = ((IndexElem *) lfirst(lc))->name;
785
786                                         /* expression index has a dummy column name */
787                                         if (attname == NULL)
788                                         {
789                                                 attname = palloc(NAMEDATALEN);
790                                                 sprintf(attname, "pg_expression_%d", i);
791                                         }
792
793                                         stmt = makeNode(CommentStmt);
794                                         stmt->objtype = OBJECT_COLUMN;
795                                         stmt->objname = list_make3(
796                                                                                 makeString(cxt->relation->schemaname),
797                                                                                 makeString(index_stmt->idxname),
798                                                                                 makeString(attname));
799                                         stmt->objargs = NIL;
800                                         stmt->comment = comment;
801
802                                         cxt->alist = lappend(cxt->alist, stmt);
803                                 }
804                         }
805
806                         /* Save it in the inh_indexes list for the time being */
807                         cxt->inh_indexes = lappend(cxt->inh_indexes, index_stmt);
808
809                         index_close(parent_index, AccessShareLock);
810                 }
811         }
812
813         /*
814          * Close the parent rel, but keep our AccessShareLock on it until xact
815          * commit.      That will prevent someone else from deleting or ALTERing the
816          * parent before the child is committed.
817          */
818         heap_close(relation, NoLock);
819 }
820
821 /*
822  * chooseIndexName
823  *
824  * Set name for unnamed index. See also the same logic in DefineIndex.
825  */
826 static char *
827 chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt)
828 {
829         Oid     namespaceId;
830         
831         namespaceId = RangeVarGetCreationNamespace(relation);
832         if (index_stmt->primary)
833         {
834                 /* no need for column list with pkey */
835                 return ChooseRelationName(relation->relname, NULL, 
836                                                                   "pkey", namespaceId);
837         }
838         else if (index_stmt->excludeOpNames != NIL)
839         {
840                 IndexElem  *iparam = (IndexElem *) linitial(index_stmt->indexParams);
841
842                 return ChooseRelationName(relation->relname, iparam->name,
843                                                                   "exclusion", namespaceId);
844         }
845         else
846         {
847                 IndexElem  *iparam = (IndexElem *) linitial(index_stmt->indexParams);
848
849                 return ChooseRelationName(relation->relname, iparam->name,
850                                                                   "key", namespaceId);
851         }
852 }
853
854 /*
855  * Generate an IndexStmt node using information from an already existing index
856  * "source_idx".  Attribute numbers should be adjusted according to attmap.
857  */
858 static IndexStmt *
859 generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
860                                                 AttrNumber *attmap)
861 {
862         Oid                     source_relid = RelationGetRelid(source_idx);
863         HeapTuple       ht_idxrel;
864         HeapTuple       ht_idx;
865         Form_pg_class idxrelrec;
866         Form_pg_index idxrec;
867         Form_pg_am      amrec;
868         oidvector  *indclass;
869         IndexStmt  *index;
870         List       *indexprs;
871         ListCell   *indexpr_item;
872         Oid                     indrelid;
873         int                     keyno;
874         Oid                     keycoltype;
875         Datum           datum;
876         bool            isnull;
877
878         /*
879          * Fetch pg_class tuple of source index.  We can't use the copy in the
880          * relcache entry because it doesn't include optional fields.
881          */
882         ht_idxrel = SearchSysCache(RELOID,
883                                                            ObjectIdGetDatum(source_relid),
884                                                            0, 0, 0);
885         if (!HeapTupleIsValid(ht_idxrel))
886                 elog(ERROR, "cache lookup failed for relation %u", source_relid);
887         idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
888
889         /* Fetch pg_index tuple for source index from relcache entry */
890         ht_idx = source_idx->rd_indextuple;
891         idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
892         indrelid = idxrec->indrelid;
893
894         /* Fetch pg_am tuple for source index from relcache entry */
895         amrec = source_idx->rd_am;
896
897         /* Extract indclass from the pg_index tuple */
898         datum = SysCacheGetAttr(INDEXRELID, ht_idx,
899                                                         Anum_pg_index_indclass, &isnull);
900         Assert(!isnull);
901         indclass = (oidvector *) DatumGetPointer(datum);
902
903         /* Begin building the IndexStmt */
904         index = makeNode(IndexStmt);
905         index->relation = cxt->relation;
906         index->accessMethod = pstrdup(NameStr(amrec->amname));
907         if (OidIsValid(idxrelrec->reltablespace))
908                 index->tableSpace = get_tablespace_name(idxrelrec->reltablespace);
909         else
910                 index->tableSpace = NULL;
911         index->unique = idxrec->indisunique;
912         index->primary = idxrec->indisprimary;
913         index->concurrent = false;
914
915         /*
916          * We don't try to preserve the name of the source index; instead, just
917          * let DefineIndex() choose a reasonable name.
918          */
919         index->idxname = NULL;
920
921         /*
922          * If the index is marked PRIMARY or has an exclusion condition, it's
923          * certainly from a constraint; else, if it's not marked UNIQUE, it
924          * certainly isn't.  If it is or might be from a constraint, we have to
925          * fetch the pg_constraint record.
926          */
927         if (index->primary || index->unique || idxrelrec->relhasexclusion)
928         {
929                 Oid             constraintId = get_index_constraint(source_relid);
930
931                 if (OidIsValid(constraintId))
932                 {
933                         HeapTuple       ht_constr;
934                         Form_pg_constraint conrec;
935
936                         ht_constr = SearchSysCache(CONSTROID,
937                                                                            ObjectIdGetDatum(constraintId),
938                                                                            0, 0, 0);
939                         if (!HeapTupleIsValid(ht_constr))
940                                 elog(ERROR, "cache lookup failed for constraint %u",
941                                          constraintId);
942                         conrec = (Form_pg_constraint) GETSTRUCT(ht_constr);
943
944                         index->isconstraint = true;
945                         index->deferrable = conrec->condeferrable;
946                         index->initdeferred = conrec->condeferred;
947
948                         /* If it's an exclusion constraint, we need the operator names */
949                         if (idxrelrec->relhasexclusion)
950                         {
951                                 Datum  *elems;
952                                 int             nElems;
953                                 int             i;
954
955                                 Assert(conrec->contype == CONSTRAINT_EXCLUSION);
956                                 /* Extract operator OIDs from the pg_constraint tuple */
957                                 datum = SysCacheGetAttr(CONSTROID, ht_constr,
958                                                                                 Anum_pg_constraint_conexclop,
959                                                                                 &isnull);
960                                 if (isnull)
961                                         elog(ERROR, "null conexclop for constraint %u",
962                                                  constraintId);
963
964                                 deconstruct_array(DatumGetArrayTypeP(datum),
965                                                                   OIDOID, sizeof(Oid), true, 'i',
966                                                                   &elems, NULL, &nElems);
967
968                                 for (i = 0; i < nElems; i++)
969                                 {
970                                         Oid                     operid = DatumGetObjectId(elems[i]);
971                                         HeapTuple       opertup;
972                                         Form_pg_operator operform;
973                                         char       *oprname;
974                                         char       *nspname;
975                                         List       *namelist;
976
977                                         opertup = SearchSysCache(OPEROID,
978                                                                                          ObjectIdGetDatum(operid),
979                                                                                          0, 0, 0);
980                                         if (!HeapTupleIsValid(opertup))
981                                                 elog(ERROR, "cache lookup failed for operator %u",
982                                                          operid);
983                                         operform = (Form_pg_operator) GETSTRUCT(opertup);
984                                         oprname = pstrdup(NameStr(operform->oprname));
985                                         /* For simplicity we always schema-qualify the op name */
986                                         nspname = get_namespace_name(operform->oprnamespace);
987                                         namelist = list_make2(makeString(nspname),
988                                                                                   makeString(oprname));
989                                         index->excludeOpNames = lappend(index->excludeOpNames,
990                                                                                                         namelist);
991                                         ReleaseSysCache(opertup);
992                                 }
993                         }
994
995                         ReleaseSysCache(ht_constr);
996                 }
997                 else
998                         index->isconstraint = false;
999         }
1000         else
1001                 index->isconstraint = false;
1002
1003         /* Get the index expressions, if any */
1004         datum = SysCacheGetAttr(INDEXRELID, ht_idx,
1005                                                         Anum_pg_index_indexprs, &isnull);
1006         if (!isnull)
1007         {
1008                 char       *exprsString;
1009
1010                 exprsString = TextDatumGetCString(datum);
1011                 indexprs = (List *) stringToNode(exprsString);
1012         }
1013         else
1014                 indexprs = NIL;
1015
1016         /* Build the list of IndexElem */
1017         index->indexParams = NIL;
1018
1019         indexpr_item = list_head(indexprs);
1020         for (keyno = 0; keyno < idxrec->indnatts; keyno++)
1021         {
1022                 IndexElem  *iparam;
1023                 AttrNumber      attnum = idxrec->indkey.values[keyno];
1024                 int16           opt = source_idx->rd_indoption[keyno];
1025
1026                 iparam = makeNode(IndexElem);
1027
1028                 if (AttributeNumberIsValid(attnum))
1029                 {
1030                         /* Simple index column */
1031                         char       *attname;
1032
1033                         attname = get_relid_attribute_name(indrelid, attnum);
1034                         keycoltype = get_atttype(indrelid, attnum);
1035
1036                         iparam->name = attname;
1037                         iparam->expr = NULL;
1038                 }
1039                 else
1040                 {
1041                         /* Expressional index */
1042                         Node       *indexkey;
1043
1044                         if (indexpr_item == NULL)
1045                                 elog(ERROR, "too few entries in indexprs list");
1046                         indexkey = (Node *) lfirst(indexpr_item);
1047                         indexpr_item = lnext(indexpr_item);
1048
1049                         /* OK to modify indexkey since we are working on a private copy */
1050                         change_varattnos_of_a_node(indexkey, attmap);
1051
1052                         iparam->name = NULL;
1053                         iparam->expr = indexkey;
1054
1055                         keycoltype = exprType(indexkey);
1056                 }
1057
1058                 /* Add the operator class name, if non-default */
1059                 iparam->opclass = get_opclass(indclass->values[keyno], keycoltype);
1060
1061                 iparam->ordering = SORTBY_DEFAULT;
1062                 iparam->nulls_ordering = SORTBY_NULLS_DEFAULT;
1063
1064                 /* Adjust options if necessary */
1065                 if (amrec->amcanorder)
1066                 {
1067                         /*
1068                          * If it supports sort ordering, copy DESC and NULLS opts. Don't
1069                          * set non-default settings unnecessarily, though, so as to
1070                          * improve the chance of recognizing equivalence to constraint
1071                          * indexes.
1072                          */
1073                         if (opt & INDOPTION_DESC)
1074                         {
1075                                 iparam->ordering = SORTBY_DESC;
1076                                 if ((opt & INDOPTION_NULLS_FIRST) == 0)
1077                                         iparam->nulls_ordering = SORTBY_NULLS_LAST;
1078                         }
1079                         else
1080                         {
1081                                 if (opt & INDOPTION_NULLS_FIRST)
1082                                         iparam->nulls_ordering = SORTBY_NULLS_FIRST;
1083                         }
1084                 }
1085
1086                 index->indexParams = lappend(index->indexParams, iparam);
1087         }
1088
1089         /* Copy reloptions if any */
1090         datum = SysCacheGetAttr(RELOID, ht_idxrel,
1091                                                         Anum_pg_class_reloptions, &isnull);
1092         if (!isnull)
1093                 index->options = untransformRelOptions(datum);
1094
1095         /* If it's a partial index, decompile and append the predicate */
1096         datum = SysCacheGetAttr(INDEXRELID, ht_idx,
1097                                                         Anum_pg_index_indpred, &isnull);
1098         if (!isnull)
1099         {
1100                 char       *pred_str;
1101
1102                 /* Convert text string to node tree */
1103                 pred_str = TextDatumGetCString(datum);
1104                 index->whereClause = (Node *) stringToNode(pred_str);
1105                 /* Adjust attribute numbers */
1106                 change_varattnos_of_a_node(index->whereClause, attmap);
1107         }
1108
1109         /* Clean up */
1110         ReleaseSysCache(ht_idxrel);
1111
1112         return index;
1113 }
1114
1115 /*
1116  * get_opclass                  - fetch name of an index operator class
1117  *
1118  * If the opclass is the default for the given actual_datatype, then
1119  * the return value is NIL.
1120  */
1121 static List *
1122 get_opclass(Oid opclass, Oid actual_datatype)
1123 {
1124         HeapTuple       ht_opc;
1125         Form_pg_opclass opc_rec;
1126         List       *result = NIL;
1127
1128         ht_opc = SearchSysCache(CLAOID,
1129                                                         ObjectIdGetDatum(opclass),
1130                                                         0, 0, 0);
1131         if (!HeapTupleIsValid(ht_opc))
1132                 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1133         opc_rec = (Form_pg_opclass) GETSTRUCT(ht_opc);
1134
1135         if (GetDefaultOpClass(actual_datatype, opc_rec->opcmethod) != opclass)
1136         {
1137                 /* For simplicity, we always schema-qualify the name */
1138                 char       *nsp_name = get_namespace_name(opc_rec->opcnamespace);
1139                 char       *opc_name = pstrdup(NameStr(opc_rec->opcname));
1140
1141                 result = list_make2(makeString(nsp_name), makeString(opc_name));
1142         }
1143
1144         ReleaseSysCache(ht_opc);
1145         return result;
1146 }
1147
1148
1149 /*
1150  * transformIndexConstraints
1151  *              Handle UNIQUE, PRIMARY KEY, EXCLUDE constraints, which create indexes.
1152  *              We also merge in any index definitions arising from
1153  *              LIKE ... INCLUDING INDEXES.
1154  */
1155 static void
1156 transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
1157 {
1158         IndexStmt  *index;
1159         List       *indexlist = NIL;
1160         ListCell   *lc;
1161
1162         /*
1163          * Run through the constraints that need to generate an index. For PRIMARY
1164          * KEY, mark each column as NOT NULL and create an index. For UNIQUE or
1165          * EXCLUDE, create an index as for PRIMARY KEY, but do not insist on NOT
1166          * NULL.
1167          */
1168         foreach(lc, cxt->ixconstraints)
1169         {
1170                 Constraint *constraint = (Constraint *) lfirst(lc);
1171
1172                 Assert(IsA(constraint, Constraint));
1173                 Assert(constraint->contype == CONSTR_PRIMARY ||
1174                            constraint->contype == CONSTR_UNIQUE ||
1175                            constraint->contype == CONSTR_EXCLUSION);
1176
1177                 index = transformIndexConstraint(constraint, cxt);
1178
1179                 indexlist = lappend(indexlist, index);
1180         }
1181
1182         /* Add in any indexes defined by LIKE ... INCLUDING INDEXES */
1183         foreach(lc, cxt->inh_indexes)
1184         {
1185                 index = (IndexStmt *) lfirst(lc);
1186
1187                 if (index->primary)
1188                 {
1189                         if (cxt->pkey != NULL)
1190                                 ereport(ERROR,
1191                                                 (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
1192                                                  errmsg("multiple primary keys for table \"%s\" are not allowed",
1193                                                                 cxt->relation->relname)));
1194                         cxt->pkey = index;
1195                 }
1196
1197                 indexlist = lappend(indexlist, index);
1198         }
1199
1200         /*
1201          * Scan the index list and remove any redundant index specifications. This
1202          * can happen if, for instance, the user writes UNIQUE PRIMARY KEY. A
1203          * strict reading of SQL92 would suggest raising an error instead, but
1204          * that strikes me as too anal-retentive. - tgl 2001-02-14
1205          *
1206          * XXX in ALTER TABLE case, it'd be nice to look for duplicate
1207          * pre-existing indexes, too.
1208          */
1209         Assert(cxt->alist == NIL);
1210         if (cxt->pkey != NULL)
1211         {
1212                 /* Make sure we keep the PKEY index in preference to others... */
1213                 cxt->alist = list_make1(cxt->pkey);
1214         }
1215
1216         foreach(lc, indexlist)
1217         {
1218                 bool            keep = true;
1219                 ListCell   *k;
1220
1221                 index = lfirst(lc);
1222
1223                 /* if it's pkey, it's already in cxt->alist */
1224                 if (index == cxt->pkey)
1225                         continue;
1226
1227                 foreach(k, cxt->alist)
1228                 {
1229                         IndexStmt  *priorindex = lfirst(k);
1230
1231                         if (equal(index->indexParams, priorindex->indexParams) &&
1232                                 equal(index->whereClause, priorindex->whereClause) &&
1233                                 equal(index->excludeOpNames, priorindex->excludeOpNames) &&
1234                                 strcmp(index->accessMethod, priorindex->accessMethod) == 0 &&
1235                                 index->deferrable == priorindex->deferrable &&
1236                                 index->initdeferred == priorindex->initdeferred)
1237                         {
1238                                 priorindex->unique |= index->unique;
1239
1240                                 /*
1241                                  * If the prior index is as yet unnamed, and this one is
1242                                  * named, then transfer the name to the prior index. This
1243                                  * ensures that if we have named and unnamed constraints,
1244                                  * we'll use (at least one of) the names for the index.
1245                                  */
1246                                 if (priorindex->idxname == NULL)
1247                                         priorindex->idxname = index->idxname;
1248                                 keep = false;
1249                                 break;
1250                         }
1251                 }
1252
1253                 if (keep)
1254                         cxt->alist = lappend(cxt->alist, index);
1255         }
1256 }
1257
1258 /*
1259  * transformIndexConstraint
1260  *              Transform one UNIQUE, PRIMARY KEY, or EXCLUDE constraint for
1261  *              transformIndexConstraints.
1262  */
1263 static IndexStmt *
1264 transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
1265 {
1266         IndexStmt  *index;
1267         ListCell   *lc;
1268
1269         index = makeNode(IndexStmt);
1270
1271         index->unique = (constraint->contype != CONSTR_EXCLUSION);
1272         index->primary = (constraint->contype == CONSTR_PRIMARY);
1273         if (index->primary)
1274         {
1275                 if (cxt->pkey != NULL)
1276                         ereport(ERROR,
1277                                         (errcode(ERRCODE_INVALID_TABLE_DEFINITION),
1278                          errmsg("multiple primary keys for table \"%s\" are not allowed",
1279                                         cxt->relation->relname)));
1280                 cxt->pkey = index;
1281
1282                 /*
1283                  * In ALTER TABLE case, a primary index might already exist, but
1284                  * DefineIndex will check for it.
1285                  */
1286         }
1287         index->isconstraint = true;
1288         index->deferrable = constraint->deferrable;
1289         index->initdeferred = constraint->initdeferred;
1290
1291         if (constraint->conname != NULL)
1292                 index->idxname = pstrdup(constraint->conname);
1293         else
1294                 index->idxname = NULL;  /* DefineIndex will choose name */
1295
1296         index->relation = cxt->relation;
1297         index->accessMethod = constraint->access_method ? constraint->access_method : DEFAULT_INDEX_TYPE;
1298         index->options = constraint->options;
1299         index->tableSpace = constraint->indexspace;
1300         index->whereClause = constraint->where_clause;
1301         index->indexParams = NIL;
1302         index->excludeOpNames = NIL;
1303         index->concurrent = false;
1304
1305         /*
1306          * If it's an EXCLUDE constraint, the grammar returns a list of pairs
1307          * of IndexElems and operator names.  We have to break that apart into
1308          * separate lists.
1309          */
1310         if (constraint->contype == CONSTR_EXCLUSION)
1311         {
1312                 foreach(lc, constraint->exclusions)
1313                 {
1314                         List    *pair = (List *) lfirst(lc);
1315                         IndexElem *elem;
1316                         List   *opname;
1317
1318                         Assert(list_length(pair) == 2);
1319                         elem = (IndexElem *) linitial(pair);
1320                         Assert(IsA(elem, IndexElem));
1321                         opname = (List *) lsecond(pair);
1322                         Assert(IsA(opname, List));
1323
1324                         index->indexParams = lappend(index->indexParams, elem);
1325                         index->excludeOpNames = lappend(index->excludeOpNames, opname);
1326                 }
1327
1328                 return index;
1329         }
1330
1331         /*
1332          * For UNIQUE and PRIMARY KEY, we just have a list of column names.
1333          *
1334          * Make sure referenced keys exist.  If we are making a PRIMARY KEY index,
1335          * also make sure they are NOT NULL, if possible. (Although we could leave
1336          * it to DefineIndex to mark the columns NOT NULL, it's more efficient to
1337          * get it right the first time.)
1338          */
1339         foreach(lc, constraint->keys)
1340         {
1341                 char       *key = strVal(lfirst(lc));
1342                 bool            found = false;
1343                 ColumnDef  *column = NULL;
1344                 ListCell   *columns;
1345                 IndexElem  *iparam;
1346
1347                 foreach(columns, cxt->columns)
1348                 {
1349                         column = (ColumnDef *) lfirst(columns);
1350                         Assert(IsA(column, ColumnDef));
1351                         if (strcmp(column->colname, key) == 0)
1352                         {
1353                                 found = true;
1354                                 break;
1355                         }
1356                 }
1357                 if (found)
1358                 {
1359                         /* found column in the new table; force it to be NOT NULL */
1360                         if (constraint->contype == CONSTR_PRIMARY)
1361                                 column->is_not_null = TRUE;
1362                 }
1363                 else if (SystemAttributeByName(key, cxt->hasoids) != NULL)
1364                 {
1365                         /*
1366                          * column will be a system column in the new table, so accept it.
1367                          * System columns can't ever be null, so no need to worry about
1368                          * PRIMARY/NOT NULL constraint.
1369                          */
1370                         found = true;
1371                 }
1372                 else if (cxt->inhRelations)
1373                 {
1374                         /* try inherited tables */
1375                         ListCell   *inher;
1376
1377                         foreach(inher, cxt->inhRelations)
1378                         {
1379                                 RangeVar   *inh = (RangeVar *) lfirst(inher);
1380                                 Relation        rel;
1381                                 int                     count;
1382
1383                                 Assert(IsA(inh, RangeVar));
1384                                 rel = heap_openrv(inh, AccessShareLock);
1385                                 if (rel->rd_rel->relkind != RELKIND_RELATION)
1386                                         ereport(ERROR,
1387                                                         (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1388                                                    errmsg("inherited relation \"%s\" is not a table",
1389                                                                   inh->relname)));
1390                                 for (count = 0; count < rel->rd_att->natts; count++)
1391                                 {
1392                                         Form_pg_attribute inhattr = rel->rd_att->attrs[count];
1393                                         char       *inhname = NameStr(inhattr->attname);
1394
1395                                         if (inhattr->attisdropped)
1396                                                 continue;
1397                                         if (strcmp(key, inhname) == 0)
1398                                         {
1399                                                 found = true;
1400
1401                                                 /*
1402                                                  * We currently have no easy way to force an inherited
1403                                                  * column to be NOT NULL at creation, if its parent
1404                                                  * wasn't so already. We leave it to DefineIndex to
1405                                                  * fix things up in this case.
1406                                                  */
1407                                                 break;
1408                                         }
1409                                 }
1410                                 heap_close(rel, NoLock);
1411                                 if (found)
1412                                         break;
1413                         }
1414                 }
1415
1416                 /*
1417                  * In the ALTER TABLE case, don't complain about index keys not
1418                  * created in the command; they may well exist already. DefineIndex
1419                  * will complain about them if not, and will also take care of marking
1420                  * them NOT NULL.
1421                  */
1422                 if (!found && !cxt->isalter)
1423                         ereport(ERROR,
1424                                         (errcode(ERRCODE_UNDEFINED_COLUMN),
1425                                          errmsg("column \"%s\" named in key does not exist",
1426                                                         key)));
1427
1428                 /* Check for PRIMARY KEY(foo, foo) */
1429                 foreach(columns, index->indexParams)
1430                 {
1431                         iparam = (IndexElem *) lfirst(columns);
1432                         if (iparam->name && strcmp(key, iparam->name) == 0)
1433                         {
1434                                 if (index->primary)
1435                                         ereport(ERROR,
1436                                                         (errcode(ERRCODE_DUPLICATE_COLUMN),
1437                                                          errmsg("column \"%s\" appears twice in primary key constraint",
1438                                                                         key)));
1439                                 else
1440                                         ereport(ERROR,
1441                                                         (errcode(ERRCODE_DUPLICATE_COLUMN),
1442                                         errmsg("column \"%s\" appears twice in unique constraint",
1443                                                    key)));
1444                         }
1445                 }
1446
1447                 /* OK, add it to the index definition */
1448                 iparam = makeNode(IndexElem);
1449                 iparam->name = pstrdup(key);
1450                 iparam->expr = NULL;
1451                 iparam->opclass = NIL;
1452                 iparam->ordering = SORTBY_DEFAULT;
1453                 iparam->nulls_ordering = SORTBY_NULLS_DEFAULT;
1454                 index->indexParams = lappend(index->indexParams, iparam);
1455         }
1456
1457         return index;
1458 }
1459
1460 /*
1461  * transformFKConstraints
1462  *              handle FOREIGN KEY constraints
1463  */
1464 static void
1465 transformFKConstraints(ParseState *pstate, CreateStmtContext *cxt,
1466                                            bool skipValidation, bool isAddConstraint)
1467 {
1468         ListCell   *fkclist;
1469
1470         if (cxt->fkconstraints == NIL)
1471                 return;
1472
1473         /*
1474          * If CREATE TABLE or adding a column with NULL default, we can safely
1475          * skip validation of the constraint.
1476          */
1477         if (skipValidation)
1478         {
1479                 foreach(fkclist, cxt->fkconstraints)
1480                 {
1481                         Constraint *constraint = (Constraint *) lfirst(fkclist);
1482
1483                         constraint->skip_validation = true;
1484                 }
1485         }
1486
1487         /*
1488          * For CREATE TABLE or ALTER TABLE ADD COLUMN, gin up an ALTER TABLE ADD
1489          * CONSTRAINT command to execute after the basic command is complete. (If
1490          * called from ADD CONSTRAINT, that routine will add the FK constraints to
1491          * its own subcommand list.)
1492          *
1493          * Note: the ADD CONSTRAINT command must also execute after any index
1494          * creation commands.  Thus, this should run after
1495          * transformIndexConstraints, so that the CREATE INDEX commands are
1496          * already in cxt->alist.
1497          */
1498         if (!isAddConstraint)
1499         {
1500                 AlterTableStmt *alterstmt = makeNode(AlterTableStmt);
1501
1502                 alterstmt->relation = cxt->relation;
1503                 alterstmt->cmds = NIL;
1504                 alterstmt->relkind = OBJECT_TABLE;
1505
1506                 foreach(fkclist, cxt->fkconstraints)
1507                 {
1508                         Constraint *constraint = (Constraint *) lfirst(fkclist);
1509                         AlterTableCmd *altercmd = makeNode(AlterTableCmd);
1510
1511                         altercmd->subtype = AT_ProcessedConstraint;
1512                         altercmd->name = NULL;
1513                         altercmd->def = (Node *) constraint;
1514                         alterstmt->cmds = lappend(alterstmt->cmds, altercmd);
1515                 }
1516
1517                 cxt->alist = lappend(cxt->alist, alterstmt);
1518         }
1519 }
1520
1521 /*
1522  * transformIndexStmt - parse analysis for CREATE INDEX
1523  *
1524  * Note: this is a no-op for an index not using either index expressions or
1525  * a predicate expression.      There are several code paths that create indexes
1526  * without bothering to call this, because they know they don't have any
1527  * such expressions to deal with.
1528  */
1529 IndexStmt *
1530 transformIndexStmt(IndexStmt *stmt, const char *queryString)
1531 {
1532         Relation        rel;
1533         ParseState *pstate;
1534         RangeTblEntry *rte;
1535         ListCell   *l;
1536
1537         /*
1538          * We must not scribble on the passed-in IndexStmt, so copy it.  (This is
1539          * overkill, but easy.)
1540          */
1541         stmt = (IndexStmt *) copyObject(stmt);
1542
1543         /*
1544          * Open the parent table with appropriate locking.      We must do this
1545          * because addRangeTableEntry() would acquire only AccessShareLock,
1546          * leaving DefineIndex() needing to do a lock upgrade with consequent risk
1547          * of deadlock.  Make sure this stays in sync with the type of lock
1548          * DefineIndex() wants.
1549          */
1550         rel = heap_openrv(stmt->relation,
1551                                   (stmt->concurrent ? ShareUpdateExclusiveLock : ShareLock));
1552
1553         /* Set up pstate */
1554         pstate = make_parsestate(NULL);
1555         pstate->p_sourcetext = queryString;
1556
1557         /*
1558          * Put the parent table into the rtable so that the expressions can refer
1559          * to its fields without qualification.
1560          */
1561         rte = addRangeTableEntry(pstate, stmt->relation, NULL, false, true);
1562
1563         /* no to join list, yes to namespaces */
1564         addRTEtoQuery(pstate, rte, false, true, true);
1565
1566         /* take care of the where clause */
1567         if (stmt->whereClause)
1568                 stmt->whereClause = transformWhereClause(pstate,
1569                                                                                                  stmt->whereClause,
1570                                                                                                  "WHERE");
1571
1572         /* take care of any index expressions */
1573         foreach(l, stmt->indexParams)
1574         {
1575                 IndexElem  *ielem = (IndexElem *) lfirst(l);
1576
1577                 if (ielem->expr)
1578                 {
1579                         ielem->expr = transformExpr(pstate, ielem->expr);
1580
1581                         /*
1582                          * We check only that the result type is legitimate; this is for
1583                          * consistency with what transformWhereClause() checks for the
1584                          * predicate.  DefineIndex() will make more checks.
1585                          */
1586                         if (expression_returns_set(ielem->expr))
1587                                 ereport(ERROR,
1588                                                 (errcode(ERRCODE_DATATYPE_MISMATCH),
1589                                                  errmsg("index expression cannot return a set")));
1590                 }
1591         }
1592
1593         /*
1594          * Check that only the base rel is mentioned.
1595          */
1596         if (list_length(pstate->p_rtable) != 1)
1597                 ereport(ERROR,
1598                                 (errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
1599                                  errmsg("index expressions and predicates can refer only to the table being indexed")));
1600
1601         free_parsestate(pstate);
1602
1603         /* Close relation, but keep the lock */
1604         heap_close(rel, NoLock);
1605
1606         return stmt;
1607 }
1608
1609
1610 /*
1611  * transformRuleStmt -
1612  *        transform a CREATE RULE Statement. The action is a list of parse
1613  *        trees which is transformed into a list of query trees, and we also
1614  *        transform the WHERE clause if any.
1615  *
1616  * actions and whereClause are output parameters that receive the
1617  * transformed results.
1618  *
1619  * Note that we must not scribble on the passed-in RuleStmt, so we do
1620  * copyObject() on the actions and WHERE clause.
1621  */
1622 void
1623 transformRuleStmt(RuleStmt *stmt, const char *queryString,
1624                                   List **actions, Node **whereClause)
1625 {
1626         Relation        rel;
1627         ParseState *pstate;
1628         RangeTblEntry *oldrte;
1629         RangeTblEntry *newrte;
1630
1631         /*
1632          * To avoid deadlock, make sure the first thing we do is grab
1633          * AccessExclusiveLock on the target relation.  This will be needed by
1634          * DefineQueryRewrite(), and we don't want to grab a lesser lock
1635          * beforehand.
1636          */
1637         rel = heap_openrv(stmt->relation, AccessExclusiveLock);
1638
1639         /* Set up pstate */
1640         pstate = make_parsestate(NULL);
1641         pstate->p_sourcetext = queryString;
1642
1643         /*
1644          * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to 2.
1645          * Set up their RTEs in the main pstate for use in parsing the rule
1646          * qualification.
1647          */
1648         oldrte = addRangeTableEntryForRelation(pstate, rel,
1649                                                                                    makeAlias("old", NIL),
1650                                                                                    false, false);
1651         newrte = addRangeTableEntryForRelation(pstate, rel,
1652                                                                                    makeAlias("new", NIL),
1653                                                                                    false, false);
1654         /* Must override addRangeTableEntry's default access-check flags */
1655         oldrte->requiredPerms = 0;
1656         newrte->requiredPerms = 0;
1657
1658         /*
1659          * They must be in the namespace too for lookup purposes, but only add the
1660          * one(s) that are relevant for the current kind of rule.  In an UPDATE
1661          * rule, quals must refer to OLD.field or NEW.field to be unambiguous, but
1662          * there's no need to be so picky for INSERT & DELETE.  We do not add them
1663          * to the joinlist.
1664          */
1665         switch (stmt->event)
1666         {
1667                 case CMD_SELECT:
1668                         addRTEtoQuery(pstate, oldrte, false, true, true);
1669                         break;
1670                 case CMD_UPDATE:
1671                         addRTEtoQuery(pstate, oldrte, false, true, true);
1672                         addRTEtoQuery(pstate, newrte, false, true, true);
1673                         break;
1674                 case CMD_INSERT:
1675                         addRTEtoQuery(pstate, newrte, false, true, true);
1676                         break;
1677                 case CMD_DELETE:
1678                         addRTEtoQuery(pstate, oldrte, false, true, true);
1679                         break;
1680                 default:
1681                         elog(ERROR, "unrecognized event type: %d",
1682                                  (int) stmt->event);
1683                         break;
1684         }
1685
1686         /* take care of the where clause */
1687         *whereClause = transformWhereClause(pstate,
1688                                                                           (Node *) copyObject(stmt->whereClause),
1689                                                                                 "WHERE");
1690
1691         if (list_length(pstate->p_rtable) != 2)         /* naughty, naughty... */
1692                 ereport(ERROR,
1693                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1694                                  errmsg("rule WHERE condition cannot contain references to other relations")));
1695
1696         /* aggregates not allowed (but subselects are okay) */
1697         if (pstate->p_hasAggs)
1698                 ereport(ERROR,
1699                                 (errcode(ERRCODE_GROUPING_ERROR),
1700                    errmsg("cannot use aggregate function in rule WHERE condition")));
1701         if (pstate->p_hasWindowFuncs)
1702                 ereport(ERROR,
1703                                 (errcode(ERRCODE_WINDOWING_ERROR),
1704                           errmsg("cannot use window function in rule WHERE condition")));
1705
1706         /*
1707          * 'instead nothing' rules with a qualification need a query rangetable so
1708          * the rewrite handler can add the negated rule qualification to the
1709          * original query. We create a query with the new command type CMD_NOTHING
1710          * here that is treated specially by the rewrite system.
1711          */
1712         if (stmt->actions == NIL)
1713         {
1714                 Query      *nothing_qry = makeNode(Query);
1715
1716                 nothing_qry->commandType = CMD_NOTHING;
1717                 nothing_qry->rtable = pstate->p_rtable;
1718                 nothing_qry->jointree = makeFromExpr(NIL, NULL);                /* no join wanted */
1719
1720                 *actions = list_make1(nothing_qry);
1721         }
1722         else
1723         {
1724                 ListCell   *l;
1725                 List       *newactions = NIL;
1726
1727                 /*
1728                  * transform each statement, like parse_sub_analyze()
1729                  */
1730                 foreach(l, stmt->actions)
1731                 {
1732                         Node       *action = (Node *) lfirst(l);
1733                         ParseState *sub_pstate = make_parsestate(NULL);
1734                         Query      *sub_qry,
1735                                            *top_subqry;
1736                         bool            has_old,
1737                                                 has_new;
1738
1739                         /*
1740                          * Since outer ParseState isn't parent of inner, have to pass down
1741                          * the query text by hand.
1742                          */
1743                         sub_pstate->p_sourcetext = queryString;
1744
1745                         /*
1746                          * Set up OLD/NEW in the rtable for this statement.  The entries
1747                          * are added only to relnamespace, not varnamespace, because we
1748                          * don't want them to be referred to by unqualified field names
1749                          * nor "*" in the rule actions.  We decide later whether to put
1750                          * them in the joinlist.
1751                          */
1752                         oldrte = addRangeTableEntryForRelation(sub_pstate, rel,
1753                                                                                                    makeAlias("old", NIL),
1754                                                                                                    false, false);
1755                         newrte = addRangeTableEntryForRelation(sub_pstate, rel,
1756                                                                                                    makeAlias("new", NIL),
1757                                                                                                    false, false);
1758                         oldrte->requiredPerms = 0;
1759                         newrte->requiredPerms = 0;
1760                         addRTEtoQuery(sub_pstate, oldrte, false, true, false);
1761                         addRTEtoQuery(sub_pstate, newrte, false, true, false);
1762
1763                         /* Transform the rule action statement */
1764                         top_subqry = transformStmt(sub_pstate,
1765                                                                            (Node *) copyObject(action));
1766
1767                         /*
1768                          * We cannot support utility-statement actions (eg NOTIFY) with
1769                          * nonempty rule WHERE conditions, because there's no way to make
1770                          * the utility action execute conditionally.
1771                          */
1772                         if (top_subqry->commandType == CMD_UTILITY &&
1773                                 *whereClause != NULL)
1774                                 ereport(ERROR,
1775                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1776                                                  errmsg("rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions")));
1777
1778                         /*
1779                          * If the action is INSERT...SELECT, OLD/NEW have been pushed down
1780                          * into the SELECT, and that's what we need to look at. (Ugly
1781                          * kluge ... try to fix this when we redesign querytrees.)
1782                          */
1783                         sub_qry = getInsertSelectQuery(top_subqry, NULL);
1784
1785                         /*
1786                          * If the sub_qry is a setop, we cannot attach any qualifications
1787                          * to it, because the planner won't notice them.  This could
1788                          * perhaps be relaxed someday, but for now, we may as well reject
1789                          * such a rule immediately.
1790                          */
1791                         if (sub_qry->setOperations != NULL && *whereClause != NULL)
1792                                 ereport(ERROR,
1793                                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1794                                                  errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
1795
1796                         /*
1797                          * Validate action's use of OLD/NEW, qual too
1798                          */
1799                         has_old =
1800                                 rangeTableEntry_used((Node *) sub_qry, PRS2_OLD_VARNO, 0) ||
1801                                 rangeTableEntry_used(*whereClause, PRS2_OLD_VARNO, 0);
1802                         has_new =
1803                                 rangeTableEntry_used((Node *) sub_qry, PRS2_NEW_VARNO, 0) ||
1804                                 rangeTableEntry_used(*whereClause, PRS2_NEW_VARNO, 0);
1805
1806                         switch (stmt->event)
1807                         {
1808                                 case CMD_SELECT:
1809                                         if (has_old)
1810                                                 ereport(ERROR,
1811                                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1812                                                                  errmsg("ON SELECT rule cannot use OLD")));
1813                                         if (has_new)
1814                                                 ereport(ERROR,
1815                                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1816                                                                  errmsg("ON SELECT rule cannot use NEW")));
1817                                         break;
1818                                 case CMD_UPDATE:
1819                                         /* both are OK */
1820                                         break;
1821                                 case CMD_INSERT:
1822                                         if (has_old)
1823                                                 ereport(ERROR,
1824                                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1825                                                                  errmsg("ON INSERT rule cannot use OLD")));
1826                                         break;
1827                                 case CMD_DELETE:
1828                                         if (has_new)
1829                                                 ereport(ERROR,
1830                                                                 (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1831                                                                  errmsg("ON DELETE rule cannot use NEW")));
1832                                         break;
1833                                 default:
1834                                         elog(ERROR, "unrecognized event type: %d",
1835                                                  (int) stmt->event);
1836                                         break;
1837                         }
1838
1839                         /*
1840                          * For efficiency's sake, add OLD to the rule action's jointree
1841                          * only if it was actually referenced in the statement or qual.
1842                          *
1843                          * For INSERT, NEW is not really a relation (only a reference to
1844                          * the to-be-inserted tuple) and should never be added to the
1845                          * jointree.
1846                          *
1847                          * For UPDATE, we treat NEW as being another kind of reference to
1848                          * OLD, because it represents references to *transformed* tuples
1849                          * of the existing relation.  It would be wrong to enter NEW
1850                          * separately in the jointree, since that would cause a double
1851                          * join of the updated relation.  It's also wrong to fail to make
1852                          * a jointree entry if only NEW and not OLD is mentioned.
1853                          */
1854                         if (has_old || (has_new && stmt->event == CMD_UPDATE))
1855                         {
1856                                 /*
1857                                  * If sub_qry is a setop, manipulating its jointree will do no
1858                                  * good at all, because the jointree is dummy. (This should be
1859                                  * a can't-happen case because of prior tests.)
1860                                  */
1861                                 if (sub_qry->setOperations != NULL)
1862                                         ereport(ERROR,
1863                                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1864                                                          errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
1865                                 /* hack so we can use addRTEtoQuery() */
1866                                 sub_pstate->p_rtable = sub_qry->rtable;
1867                                 sub_pstate->p_joinlist = sub_qry->jointree->fromlist;
1868                                 addRTEtoQuery(sub_pstate, oldrte, true, false, false);
1869                                 sub_qry->jointree->fromlist = sub_pstate->p_joinlist;
1870                         }
1871
1872                         newactions = lappend(newactions, top_subqry);
1873
1874                         free_parsestate(sub_pstate);
1875                 }
1876
1877                 *actions = newactions;
1878         }
1879
1880         free_parsestate(pstate);
1881
1882         /* Close relation, but keep the exclusive lock */
1883         heap_close(rel, NoLock);
1884 }
1885
1886
1887 /*
1888  * transformAlterTableStmt -
1889  *              parse analysis for ALTER TABLE
1890  *
1891  * Returns a List of utility commands to be done in sequence.  One of these
1892  * will be the transformed AlterTableStmt, but there may be additional actions
1893  * to be done before and after the actual AlterTable() call.
1894  */
1895 List *
1896 transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString)
1897 {
1898         Relation        rel;
1899         ParseState *pstate;
1900         CreateStmtContext cxt;
1901         List       *result;
1902         List       *save_alist;
1903         ListCell   *lcmd,
1904                            *l;
1905         List       *newcmds = NIL;
1906         bool            skipValidation = true;
1907         AlterTableCmd *newcmd;
1908
1909         /*
1910          * We must not scribble on the passed-in AlterTableStmt, so copy it. (This
1911          * is overkill, but easy.)
1912          */
1913         stmt = (AlterTableStmt *) copyObject(stmt);
1914
1915         /*
1916          * Acquire exclusive lock on the target relation, which will be held until
1917          * end of transaction.  This ensures any decisions we make here based on
1918          * the state of the relation will still be good at execution. We must get
1919          * exclusive lock now because execution will; taking a lower grade lock
1920          * now and trying to upgrade later risks deadlock.
1921          */
1922         rel = relation_openrv(stmt->relation, AccessExclusiveLock);
1923
1924         /* Set up pstate */
1925         pstate = make_parsestate(NULL);
1926         pstate->p_sourcetext = queryString;
1927
1928         cxt.stmtType = "ALTER TABLE";
1929         cxt.relation = stmt->relation;
1930         cxt.rel = rel;
1931         cxt.inhRelations = NIL;
1932         cxt.isalter = true;
1933         cxt.hasoids = false;            /* need not be right */
1934         cxt.columns = NIL;
1935         cxt.ckconstraints = NIL;
1936         cxt.fkconstraints = NIL;
1937         cxt.ixconstraints = NIL;
1938         cxt.inh_indexes = NIL;
1939         cxt.blist = NIL;
1940         cxt.alist = NIL;
1941         cxt.pkey = NULL;
1942
1943         /*
1944          * The only subtypes that currently require parse transformation handling
1945          * are ADD COLUMN and ADD CONSTRAINT.  These largely re-use code from
1946          * CREATE TABLE.
1947          */
1948         foreach(lcmd, stmt->cmds)
1949         {
1950                 AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
1951
1952                 switch (cmd->subtype)
1953                 {
1954                         case AT_AddColumn:
1955                         case AT_AddColumnToView:
1956                                 {
1957                                         ColumnDef  *def = (ColumnDef *) cmd->def;
1958
1959                                         Assert(IsA(def, ColumnDef));
1960                                         transformColumnDefinition(pstate, &cxt, def);
1961
1962                                         /*
1963                                          * If the column has a non-null default, we can't skip
1964                                          * validation of foreign keys.
1965                                          */
1966                                         if (def->raw_default != NULL)
1967                                                 skipValidation = false;
1968
1969                                         /*
1970                                          * All constraints are processed in other ways. Remove the
1971                                          * original list
1972                                          */
1973                                         def->constraints = NIL;
1974
1975                                         newcmds = lappend(newcmds, cmd);
1976                                         break;
1977                                 }
1978                         case AT_AddConstraint:
1979
1980                                 /*
1981                                  * The original AddConstraint cmd node doesn't go to newcmds
1982                                  */
1983                                 if (IsA(cmd->def, Constraint))
1984                                 {
1985                                         transformTableConstraint(pstate, &cxt,
1986                                                                                          (Constraint *) cmd->def);
1987                                         if (((Constraint *) cmd->def)->contype == CONSTR_FOREIGN)
1988                                                 skipValidation = false;
1989                                 }
1990                                 else
1991                                         elog(ERROR, "unrecognized node type: %d",
1992                                                  (int) nodeTag(cmd->def));
1993                                 break;
1994
1995                         case AT_ProcessedConstraint:
1996
1997                                 /*
1998                                  * Already-transformed ADD CONSTRAINT, so just make it look
1999                                  * like the standard case.
2000                                  */
2001                                 cmd->subtype = AT_AddConstraint;
2002                                 newcmds = lappend(newcmds, cmd);
2003                                 break;
2004
2005                         default:
2006                                 newcmds = lappend(newcmds, cmd);
2007                                 break;
2008                 }
2009         }
2010
2011         /*
2012          * transformIndexConstraints wants cxt.alist to contain only index
2013          * statements, so transfer anything we already have into save_alist
2014          * immediately.
2015          */
2016         save_alist = cxt.alist;
2017         cxt.alist = NIL;
2018
2019         /* Postprocess index and FK constraints */
2020         transformIndexConstraints(pstate, &cxt);
2021
2022         transformFKConstraints(pstate, &cxt, skipValidation, true);
2023
2024         /*
2025          * Push any index-creation commands into the ALTER, so that they can be
2026          * scheduled nicely by tablecmds.c.  Note that tablecmds.c assumes that
2027          * the IndexStmt attached to an AT_AddIndex subcommand has already been
2028          * through transformIndexStmt.
2029          */
2030         foreach(l, cxt.alist)
2031         {
2032                 Node       *idxstmt = (Node *) lfirst(l);
2033
2034                 Assert(IsA(idxstmt, IndexStmt));
2035                 newcmd = makeNode(AlterTableCmd);
2036                 newcmd->subtype = AT_AddIndex;
2037                 newcmd->def = (Node *) transformIndexStmt((IndexStmt *) idxstmt,
2038                                                                                                   queryString);
2039                 newcmds = lappend(newcmds, newcmd);
2040         }
2041         cxt.alist = NIL;
2042
2043         /* Append any CHECK or FK constraints to the commands list */
2044         foreach(l, cxt.ckconstraints)
2045         {
2046                 newcmd = makeNode(AlterTableCmd);
2047                 newcmd->subtype = AT_AddConstraint;
2048                 newcmd->def = (Node *) lfirst(l);
2049                 newcmds = lappend(newcmds, newcmd);
2050         }
2051         foreach(l, cxt.fkconstraints)
2052         {
2053                 newcmd = makeNode(AlterTableCmd);
2054                 newcmd->subtype = AT_AddConstraint;
2055                 newcmd->def = (Node *) lfirst(l);
2056                 newcmds = lappend(newcmds, newcmd);
2057         }
2058
2059         /* Close rel but keep lock */
2060         relation_close(rel, NoLock);
2061
2062         /*
2063          * Output results.
2064          */
2065         stmt->cmds = newcmds;
2066
2067         result = lappend(cxt.blist, stmt);
2068         result = list_concat(result, cxt.alist);
2069         result = list_concat(result, save_alist);
2070
2071         return result;
2072 }
2073
2074
2075 /*
2076  * Preprocess a list of column constraint clauses
2077  * to attach constraint attributes to their primary constraint nodes
2078  * and detect inconsistent/misplaced constraint attributes.
2079  *
2080  * NOTE: currently, attributes are only supported for FOREIGN KEY, UNIQUE,
2081  * and PRIMARY KEY constraints, but someday they ought to be supported
2082  * for other constraint types.
2083  */
2084 static void
2085 transformConstraintAttrs(ParseState *pstate, List *constraintList)
2086 {
2087         Constraint *lastprimarycon = NULL;
2088         bool            saw_deferrability = false;
2089         bool            saw_initially = false;
2090         ListCell   *clist;
2091
2092 #define SUPPORTS_ATTRS(node)                            \
2093         ((node) != NULL &&                                              \
2094          ((node)->contype == CONSTR_PRIMARY ||  \
2095           (node)->contype == CONSTR_UNIQUE ||   \
2096           (node)->contype == CONSTR_EXCLUSION || \
2097           (node)->contype == CONSTR_FOREIGN))
2098
2099         foreach(clist, constraintList)
2100         {
2101                 Constraint *con = (Constraint *) lfirst(clist);
2102
2103                 if (!IsA(con, Constraint))
2104                         elog(ERROR, "unrecognized node type: %d",
2105                                  (int) nodeTag(con));
2106                 switch (con->contype)
2107                 {
2108                         case CONSTR_ATTR_DEFERRABLE:
2109                                 if (!SUPPORTS_ATTRS(lastprimarycon))
2110                                         ereport(ERROR,
2111                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2112                                                          errmsg("misplaced DEFERRABLE clause"),
2113                                                          parser_errposition(pstate, con->location)));
2114                                 if (saw_deferrability)
2115                                         ereport(ERROR,
2116                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2117                                                          errmsg("multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"),
2118                                                          parser_errposition(pstate, con->location)));
2119                                 saw_deferrability = true;
2120                                 lastprimarycon->deferrable = true;
2121                                 break;
2122
2123                         case CONSTR_ATTR_NOT_DEFERRABLE:
2124                                 if (!SUPPORTS_ATTRS(lastprimarycon))
2125                                         ereport(ERROR,
2126                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2127                                                          errmsg("misplaced NOT DEFERRABLE clause"),
2128                                                          parser_errposition(pstate, con->location)));
2129                                 if (saw_deferrability)
2130                                         ereport(ERROR,
2131                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2132                                                          errmsg("multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"),
2133                                                          parser_errposition(pstate, con->location)));
2134                                 saw_deferrability = true;
2135                                 lastprimarycon->deferrable = false;
2136                                 if (saw_initially &&
2137                                         lastprimarycon->initdeferred)
2138                                         ereport(ERROR,
2139                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2140                                                          errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
2141                                                          parser_errposition(pstate, con->location)));
2142                                 break;
2143
2144                         case CONSTR_ATTR_DEFERRED:
2145                                 if (!SUPPORTS_ATTRS(lastprimarycon))
2146                                         ereport(ERROR,
2147                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2148                                                          errmsg("misplaced INITIALLY DEFERRED clause"),
2149                                                          parser_errposition(pstate, con->location)));
2150                                 if (saw_initially)
2151                                         ereport(ERROR,
2152                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2153                                                          errmsg("multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"),
2154                                                          parser_errposition(pstate, con->location)));
2155                                 saw_initially = true;
2156                                 lastprimarycon->initdeferred = true;
2157
2158                                 /*
2159                                  * If only INITIALLY DEFERRED appears, assume DEFERRABLE
2160                                  */
2161                                 if (!saw_deferrability)
2162                                         lastprimarycon->deferrable = true;
2163                                 else if (!lastprimarycon->deferrable)
2164                                         ereport(ERROR,
2165                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2166                                                          errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
2167                                                          parser_errposition(pstate, con->location)));
2168                                 break;
2169
2170                         case CONSTR_ATTR_IMMEDIATE:
2171                                 if (!SUPPORTS_ATTRS(lastprimarycon))
2172                                         ereport(ERROR,
2173                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2174                                                          errmsg("misplaced INITIALLY IMMEDIATE clause"),
2175                                                          parser_errposition(pstate, con->location)));
2176                                 if (saw_initially)
2177                                         ereport(ERROR,
2178                                                         (errcode(ERRCODE_SYNTAX_ERROR),
2179                                                          errmsg("multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"),
2180                                                          parser_errposition(pstate, con->location)));
2181                                 saw_initially = true;
2182                                 lastprimarycon->initdeferred = false;
2183                                 break;
2184
2185                         default:
2186                                 /* Otherwise it's not an attribute */
2187                                 lastprimarycon = con;
2188                                 /* reset flags for new primary node */
2189                                 saw_deferrability = false;
2190                                 saw_initially = false;
2191                                 break;
2192                 }
2193         }
2194 }
2195
2196 /*
2197  * Special handling of type definition for a column
2198  */
2199 static void
2200 transformColumnType(ParseState *pstate, ColumnDef *column)
2201 {
2202         /*
2203          * All we really need to do here is verify that the type is valid.
2204          */
2205         Type            ctype = typenameType(pstate, column->typeName, NULL);
2206
2207         ReleaseSysCache(ctype);
2208 }
2209
2210
2211 /*
2212  * transformCreateSchemaStmt -
2213  *        analyzes the CREATE SCHEMA statement
2214  *
2215  * Split the schema element list into individual commands and place
2216  * them in the result list in an order such that there are no forward
2217  * references (e.g. GRANT to a table created later in the list). Note
2218  * that the logic we use for determining forward references is
2219  * presently quite incomplete.
2220  *
2221  * SQL92 also allows constraints to make forward references, so thumb through
2222  * the table columns and move forward references to a posterior alter-table
2223  * command.
2224  *
2225  * The result is a list of parse nodes that still need to be analyzed ---
2226  * but we can't analyze the later commands until we've executed the earlier
2227  * ones, because of possible inter-object references.
2228  *
2229  * Note: this breaks the rules a little bit by modifying schema-name fields
2230  * within passed-in structs.  However, the transformation would be the same
2231  * if done over, so it should be all right to scribble on the input to this
2232  * extent.
2233  */
2234 List *
2235 transformCreateSchemaStmt(CreateSchemaStmt *stmt)
2236 {
2237         CreateSchemaStmtContext cxt;
2238         List       *result;
2239         ListCell   *elements;
2240
2241         cxt.stmtType = "CREATE SCHEMA";
2242         cxt.schemaname = stmt->schemaname;
2243         cxt.authid = stmt->authid;
2244         cxt.sequences = NIL;
2245         cxt.tables = NIL;
2246         cxt.views = NIL;
2247         cxt.indexes = NIL;
2248         cxt.triggers = NIL;
2249         cxt.grants = NIL;
2250
2251         /*
2252          * Run through each schema element in the schema element list. Separate
2253          * statements by type, and do preliminary analysis.
2254          */
2255         foreach(elements, stmt->schemaElts)
2256         {
2257                 Node       *element = lfirst(elements);
2258
2259                 switch (nodeTag(element))
2260                 {
2261                         case T_CreateSeqStmt:
2262                                 {
2263                                         CreateSeqStmt *elp = (CreateSeqStmt *) element;
2264
2265                                         setSchemaName(cxt.schemaname, &elp->sequence->schemaname);
2266                                         cxt.sequences = lappend(cxt.sequences, element);
2267                                 }
2268                                 break;
2269
2270                         case T_CreateStmt:
2271                                 {
2272                                         CreateStmt *elp = (CreateStmt *) element;
2273
2274                                         setSchemaName(cxt.schemaname, &elp->relation->schemaname);
2275
2276                                         /*
2277                                          * XXX todo: deal with constraints
2278                                          */
2279                                         cxt.tables = lappend(cxt.tables, element);
2280                                 }
2281                                 break;
2282
2283                         case T_ViewStmt:
2284                                 {
2285                                         ViewStmt   *elp = (ViewStmt *) element;
2286
2287                                         setSchemaName(cxt.schemaname, &elp->view->schemaname);
2288
2289                                         /*
2290                                          * XXX todo: deal with references between views
2291                                          */
2292                                         cxt.views = lappend(cxt.views, element);
2293                                 }
2294                                 break;
2295
2296                         case T_IndexStmt:
2297                                 {
2298                                         IndexStmt  *elp = (IndexStmt *) element;
2299
2300                                         setSchemaName(cxt.schemaname, &elp->relation->schemaname);
2301                                         cxt.indexes = lappend(cxt.indexes, element);
2302                                 }
2303                                 break;
2304
2305                         case T_CreateTrigStmt:
2306                                 {
2307                                         CreateTrigStmt *elp = (CreateTrigStmt *) element;
2308
2309                                         setSchemaName(cxt.schemaname, &elp->relation->schemaname);
2310                                         cxt.triggers = lappend(cxt.triggers, element);
2311                                 }
2312                                 break;
2313
2314                         case T_GrantStmt:
2315                                 cxt.grants = lappend(cxt.grants, element);
2316                                 break;
2317
2318                         default:
2319                                 elog(ERROR, "unrecognized node type: %d",
2320                                          (int) nodeTag(element));
2321                 }
2322         }
2323
2324         result = NIL;
2325         result = list_concat(result, cxt.sequences);
2326         result = list_concat(result, cxt.tables);
2327         result = list_concat(result, cxt.views);
2328         result = list_concat(result, cxt.indexes);
2329         result = list_concat(result, cxt.triggers);
2330         result = list_concat(result, cxt.grants);
2331
2332         return result;
2333 }
2334
2335 /*
2336  * setSchemaName
2337  *              Set or check schema name in an element of a CREATE SCHEMA command
2338  */
2339 static void
2340 setSchemaName(char *context_schema, char **stmt_schema_name)
2341 {
2342         if (*stmt_schema_name == NULL)
2343                 *stmt_schema_name = context_schema;
2344         else if (strcmp(context_schema, *stmt_schema_name) != 0)
2345                 ereport(ERROR,
2346                                 (errcode(ERRCODE_INVALID_SCHEMA_DEFINITION),
2347                                  errmsg("CREATE specifies a schema (%s) "
2348                                                 "different from the one being created (%s)",
2349                                                 *stmt_schema_name, context_schema)));
2350 }