OSDN Git Service

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