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