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.
NPnull11  * 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-2018, 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/amapi.h"
30 #include "access/htup_details.h"
31 #include "access/reloptions.h"
32 #include "catalog/dependency.h"
33 #include "catalog/heap.h"
34 #include "catalog/index.h"
35 #include "catalog/namespace.h"
36 #include "catalog/pg_am.h"
37 #include "catalog/pg_collation.h"
38 #include "catalog/pg_constraint.h"
39 #include "catalog/pg_opclass.h"
40 #include "catalog/pg_operator.h"
41 #include "catalog/pg_statistic_ext.h"
42 #include "catalog/pg_type.h"
43 #include "commands/comment.h"
44 #include "commands/defrem.h"
45 #include "commands/sequence.h"
46 #include "commands/tablecmds.h"
47 #include "commands/tablespace.h"
48 #include "miscadmin.h"
49 #include "nodes/makefuncs.h"
50 #include "nodes/nodeFuncs.h"
51 #include "optimizer/planner.h"
52 #include "parser/analyze.h"
53 #include "parser/parse_clause.h"
54 #include "parser/parse_coerce.h"
55 #include "parser/parse_collate.h"
56 #include "parser/parse_expr.h"
57 #include "parser/parse_relation.h"
58 #include "parser/parse_target.h"
59 #include "parser/parse_type.h"
60 #include "parser/parse_utilcmd.h"
61 #include "parser/parser.h"
62 #include "rewrite/rewriteManip.h"
63 #include "utils/acl.h"
64 #include "utils/builtins.h"
65 #include "utils/lsyscache.h"
66 #include "utils/partcache.h"
67 #include "utils/rel.h"
68 #include "utils/ruleutils.h"
69 #include "utils/syscache.h"
70 #include "utils/typcache.h"
71 
72 
73 /* State shared by transformCreateStmt and its subroutines */
74 typedef struct
75 {
76 	ParseState *pstate;			/* overall parser state */
77 	const char *stmtType;		/* "CREATE [FOREIGN] TABLE" or "ALTER TABLE" */
78 	RangeVar   *relation;		/* relation to create */
79 	Relation	rel;			/* opened/locked rel, if ALTER */
80 	List	   *inhRelations;	/* relations to inherit from */
81 	bool		isforeign;		/* true if CREATE/ALTER FOREIGN TABLE */
82 	bool		isalter;		/* true if altering existing table */
83 	bool		hasoids;		/* does relation have an OID column? */
84 	List	   *columns;		/* ColumnDef items */
85 	List	   *ckconstraints;	/* CHECK constraints */
86 	List	   *fkconstraints;	/* FOREIGN KEY constraints */
87 	List	   *ixconstraints;	/* index-creating constraints */
88 	List	   *likeclauses;	/* LIKE clauses that need post-processing */
89 	List	   *extstats;		/* cloned extended statistics */
90 	List	   *blist;			/* "before list" of things to do before
91 								 * creating the table */
92 	List	   *alist;			/* "after list" of things to do after creating
93 								 * the table */
94 	IndexStmt  *pkey;			/* PRIMARY KEY index, if any */
95 	bool		ispartitioned;	/* true if table is partitioned */
96 	PartitionBoundSpec *partbound;	/* transformed FOR VALUES */
97 	bool		ofType;			/* true if statement contains OF typename */
98 } CreateStmtContext;
99 
100 /* State shared by transformCreateSchemaStmt and its subroutines */
101 typedef struct
102 {
103 	const char *stmtType;		/* "CREATE SCHEMA" or "ALTER SCHEMA" */
104 	char	   *schemaname;		/* name of schema */
105 	RoleSpec   *authrole;		/* owner of schema */
106 	List	   *sequences;		/* CREATE SEQUENCE items */
107 	List	   *tables;			/* CREATE TABLE items */
108 	List	   *views;			/* CREATE VIEW items */
109 	List	   *indexes;		/* CREATE INDEX items */
110 	List	   *triggers;		/* CREATE TRIGGER items */
111 	List	   *grants;			/* GRANT items */
112 } CreateSchemaStmtContext;
113 
114 
115 static void transformColumnDefinition(CreateStmtContext *cxt,
116 						  ColumnDef *column);
117 static void transformTableConstraint(CreateStmtContext *cxt,
118 						 Constraint *constraint);
119 static void transformTableLikeClause(CreateStmtContext *cxt,
120 						 TableLikeClause *table_like_clause);
121 static void transformOfType(CreateStmtContext *cxt,
122 				TypeName *ofTypename);
123 static CreateStatsStmt *generateClonedExtStatsStmt(RangeVar *heapRel,
124 						   Oid heapRelid, Oid source_statsid);
125 static List *get_collation(Oid collation, Oid actual_datatype);
126 static List *get_opclass(Oid opclass, Oid actual_datatype);
127 static void transformIndexConstraints(CreateStmtContext *cxt);
128 static IndexStmt *transformIndexConstraint(Constraint *constraint,
129 						 CreateStmtContext *cxt);
130 static void transformExtendedStatistics(CreateStmtContext *cxt);
131 static void transformFKConstraints(CreateStmtContext *cxt,
132 					   bool skipValidation,
133 					   bool isAddConstraint);
134 static void transformCheckConstraints(CreateStmtContext *cxt,
135 						  bool skipValidation);
136 static void transformConstraintAttrs(CreateStmtContext *cxt,
137 						 List *constraintList);
138 static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column);
139 static void setSchemaName(char *context_schema, char **stmt_schema_name);
140 static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd);
141 static void validateInfiniteBounds(ParseState *pstate, List *blist);
142 static Const *transformPartitionBoundValue(ParseState *pstate, A_Const *con,
143 							 const char *colName, Oid colType, int32 colTypmod);
144 
145 
146 /*
147  * transformCreateStmt -
148  *	  parse analysis for CREATE TABLE
149  *
150  * Returns a List of utility commands to be done in sequence.  One of these
151  * will be the transformed CreateStmt, but there may be additional actions
152  * to be done before and after the actual DefineRelation() call.
153  * In addition to normal utility commands such as AlterTableStmt and
154  * IndexStmt, the result list may contain TableLikeClause(s), representing
155  * the need to perform additional parse analysis after DefineRelation().
156  *
157  * SQL allows constraints to be scattered all over, so thumb through
158  * the columns and collect all constraints into one place.
159  * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
160  * then expand those into multiple IndexStmt blocks.
161  *	  - thomas 1997-12-02
162  */
163 List *
164 transformCreateStmt(CreateStmt *stmt, const char *queryString)
165 {
166 	ParseState *pstate;
167 	CreateStmtContext cxt;
168 	List	   *result;
169 	List	   *save_alist;
170 	ListCell   *elements;
171 	Oid			namespaceid;
172 	Oid			existing_relid;
173 	ParseCallbackState pcbstate;
174 	bool		like_found = false;
175 	bool		is_foreign_table = IsA(stmt, CreateForeignTableStmt);
176 
177 	/*
178 	 * We must not scribble on the passed-in CreateStmt, so copy it.  (This is
179 	 * overkill, but easy.)
180 	 */
181 	stmt = copyObject(stmt);
182 
183 	/* Set up pstate */
184 	pstate = make_parsestate(NULL);
185 	pstate->p_sourcetext = queryString;
186 
187 	/*
188 	 * Look up the creation namespace.  This also checks permissions on the
189 	 * target namespace, locks it against concurrent drops, checks for a
190 	 * preexisting relation in that namespace with the same name, and updates
191 	 * stmt->relation->relpersistence if the selected namespace is temporary.
192 	 */
193 	setup_parser_errposition_callback(&pcbstate, pstate,
194 									  stmt->relation->location);
195 	namespaceid =
196 		RangeVarGetAndCheckCreationNamespace(stmt->relation, NoLock,
197 											 &existing_relid);
198 	cancel_parser_errposition_callback(&pcbstate);
199 
200 	/*
201 	 * If the relation already exists and the user specified "IF NOT EXISTS",
202 	 * bail out with a NOTICE.
203 	 */
204 	if (stmt->if_not_exists && OidIsValid(existing_relid))
205 	{
206 		ereport(NOTICE,
207 				(errcode(ERRCODE_DUPLICATE_TABLE),
208 				 errmsg("relation \"%s\" already exists, skipping",
209 						stmt->relation->relname)));
210 		return NIL;
211 	}
212 
213 	/*
214 	 * If the target relation name isn't schema-qualified, make it so.  This
215 	 * prevents some corner cases in which added-on rewritten commands might
216 	 * think they should apply to other relations that have the same name and
217 	 * are earlier in the search path.  But a local temp table is effectively
218 	 * specified to be in pg_temp, so no need for anything extra in that case.
219 	 */
220 	if (stmt->relation->schemaname == NULL
221 		&& stmt->relation->relpersistence != RELPERSISTENCE_TEMP)
222 		stmt->relation->schemaname = get_namespace_name(namespaceid);
223 
224 	/* Set up CreateStmtContext */
225 	cxt.pstate = pstate;
226 	if (IsA(stmt, CreateForeignTableStmt))
227 	{
228 		cxt.stmtType = "CREATE FOREIGN TABLE";
229 		cxt.isforeign = true;
230 	}
231 	else
232 	{
233 		cxt.stmtType = "CREATE TABLE";
234 		cxt.isforeign = false;
235 	}
236 	cxt.relation = stmt->relation;
237 	cxt.rel = NULL;
238 	cxt.inhRelations = stmt->inhRelations;
239 	cxt.isalter = false;
240 	cxt.columns = NIL;
241 	cxt.ckconstraints = NIL;
242 	cxt.fkconstraints = NIL;
243 	cxt.ixconstraints = NIL;
244 	cxt.likeclauses = NIL;
245 	cxt.extstats = NIL;
246 	cxt.blist = NIL;
247 	cxt.alist = NIL;
248 	cxt.pkey = NULL;
249 	cxt.ispartitioned = stmt->partspec != NULL;
250 	cxt.partbound = stmt->partbound;
251 	cxt.ofType = (stmt->ofTypename != NULL);
252 
253 	/*
254 	 * Notice that we allow OIDs here only for plain tables, even though
255 	 * foreign tables also support them.  This is necessary because the
256 	 * default_with_oids GUC must apply only to plain tables and not any other
257 	 * relkind; doing otherwise would break existing pg_dump files.  We could
258 	 * allow explicit "WITH OIDS" while not allowing default_with_oids to
259 	 * affect other relkinds, but it would complicate interpretOidsOption(),
260 	 * and right now there's no WITH OIDS option in CREATE FOREIGN TABLE
261 	 * anyway.
262 	 */
263 	cxt.hasoids = interpretOidsOption(stmt->options, !cxt.isforeign);
264 
265 	Assert(!stmt->ofTypename || !stmt->inhRelations);	/* grammar enforces */
266 
267 	if (stmt->ofTypename)
268 		transformOfType(&cxt, stmt->ofTypename);
269 
270 	if (stmt->partspec)
271 	{
272 		if (stmt->inhRelations && !stmt->partbound)
273 			ereport(ERROR,
274 					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
275 					 errmsg("cannot create partitioned table as inheritance child")));
276 	}
277 
278 	/*
279 	 * Run through each primary element in the table creation clause. Separate
280 	 * column defs from constraints, and do preliminary analysis.
281 	 */
282 	foreach(elements, stmt->tableElts)
283 	{
284 		Node	   *element = lfirst(elements);
285 
286 		switch (nodeTag(element))
287 		{
288 			case T_ColumnDef:
289 				transformColumnDefinition(&cxt, (ColumnDef *) element);
290 				break;
291 
292 			case T_Constraint:
293 				transformTableConstraint(&cxt, (Constraint *) element);
294 				break;
295 
296 			case T_TableLikeClause:
297 				like_found = true;
298 				transformTableLikeClause(&cxt, (TableLikeClause *) element);
299 				break;
300 
301 			default:
302 				elog(ERROR, "unrecognized node type: %d",
303 					 (int) nodeTag(element));
304 				break;
305 		}
306 	}
307 
308 	/*
309 	 * If we had any LIKE tables, they may require creation of an OID column
310 	 * even though the command's own WITH clause didn't ask for one (or,
311 	 * perhaps, even specifically rejected having one).  Insert a WITH option
312 	 * to ensure that happens.  We prepend to the list because the first oid
313 	 * option will be honored, and we want to override anything already there.
314 	 * (But note that DefineRelation will override this again to add an OID
315 	 * column if one appears in an inheritance parent table.)
316 	 */
317 	if (like_found && cxt.hasoids)
318 		stmt->options = lcons(makeDefElem("oids",
319 										  (Node *) makeInteger(true), -1),
320 							  stmt->options);
321 
322 	/*
323 	 * transformIndexConstraints wants cxt.alist to contain only index
324 	 * statements, so transfer anything we already have into save_alist.
325 	 */
326 	save_alist = cxt.alist;
327 	cxt.alist = NIL;
328 
329 	Assert(stmt->constraints == NIL);
330 
331 	/*
332 	 * Postprocess constraints that give rise to index definitions.
333 	 */
334 	transformIndexConstraints(&cxt);
335 
336 	/*
337 	 * Re-consideration of LIKE clauses should happen after creation of
338 	 * indexes, but before creation of foreign keys.  This order is critical
339 	 * because a LIKE clause may attempt to create a primary key.  If there's
340 	 * also a pkey in the main CREATE TABLE list, creation of that will not
341 	 * check for a duplicate at runtime (since index_check_primary_key()
342 	 * expects that we rejected dups here).  Creation of the LIKE-generated
343 	 * pkey behaves like ALTER TABLE ADD, so it will check, but obviously that
344 	 * only works if it happens second.  On the other hand, we want to make
345 	 * pkeys before foreign key constraints, in case the user tries to make a
346 	 * self-referential FK.
347 	 */
348 	cxt.alist = list_concat(cxt.alist, cxt.likeclauses);
349 
350 	/*
351 	 * Postprocess foreign-key constraints.
352 	 */
353 	transformFKConstraints(&cxt, true, false);
354 
355 	/*
356 	 * Postprocess check constraints.
357 	 */
358 	transformCheckConstraints(&cxt, !is_foreign_table ? true : false);
359 
360 	/*
361 	 * Postprocess extended statistics.
362 	 */
363 	transformExtendedStatistics(&cxt);
364 
365 	/*
366 	 * Output results.
367 	 */
368 	stmt->tableElts = cxt.columns;
369 	stmt->constraints = cxt.ckconstraints;
370 
371 	result = lappend(cxt.blist, stmt);
372 	result = list_concat(result, cxt.alist);
373 	result = list_concat(result, save_alist);
374 
375 	return result;
376 }
377 
378 /*
379  * generateSerialExtraStmts
380  *		Generate CREATE SEQUENCE and ALTER SEQUENCE ... OWNED BY statements
381  *		to create the sequence for a serial or identity column.
382  *
383  * This includes determining the name the sequence will have.  The caller
384  * can ask to get back the name components by passing non-null pointers
385  * for snamespace_p and sname_p.
386  */
387 static void
388 generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column,
389 						 Oid seqtypid, List *seqoptions, bool for_identity,
390 						 char **snamespace_p, char **sname_p)
391 {
392 	ListCell   *option;
393 	DefElem    *nameEl = NULL;
394 	Oid			snamespaceid;
395 	char	   *snamespace;
396 	char	   *sname;
397 	CreateSeqStmt *seqstmt;
398 	AlterSeqStmt *altseqstmt;
399 	List	   *attnamelist;
400 
401 	/*
402 	 * Determine namespace and name to use for the sequence.
403 	 *
404 	 * First, check if a sequence name was passed in as an option.  This is
405 	 * used by pg_dump.  Else, generate a name.
406 	 *
407 	 * Although we use ChooseRelationName, it's not guaranteed that the
408 	 * selected sequence name won't conflict; given sufficiently long field
409 	 * names, two different serial columns in the same table could be assigned
410 	 * the same sequence name, and we'd not notice since we aren't creating
411 	 * the sequence quite yet.  In practice this seems quite unlikely to be a
412 	 * problem, especially since few people would need two serial columns in
413 	 * one table.
414 	 */
415 	foreach(option, seqoptions)
416 	{
417 		DefElem    *defel = lfirst_node(DefElem, option);
418 
419 		if (strcmp(defel->defname, "sequence_name") == 0)
420 		{
421 			if (nameEl)
422 				ereport(ERROR,
423 						(errcode(ERRCODE_SYNTAX_ERROR),
424 						 errmsg("conflicting or redundant options")));
425 			nameEl = defel;
426 		}
427 	}
428 
429 	if (nameEl)
430 	{
431 		RangeVar   *rv = makeRangeVarFromNameList(castNode(List, nameEl->arg));
432 
433 		snamespace = rv->schemaname;
434 		if (!snamespace)
435 		{
436 			/* Given unqualified SEQUENCE NAME, select namespace */
437 			if (cxt->rel)
438 				snamespaceid = RelationGetNamespace(cxt->rel);
439 			else
440 				snamespaceid = RangeVarGetCreationNamespace(cxt->relation);
441 			snamespace = get_namespace_name(snamespaceid);
442 		}
443 		sname = rv->relname;
444 		/* Remove the SEQUENCE NAME item from seqoptions */
445 		seqoptions = list_delete_ptr(seqoptions, nameEl);
446 	}
447 	else
448 	{
449 		if (cxt->rel)
450 			snamespaceid = RelationGetNamespace(cxt->rel);
451 		else
452 		{
453 			snamespaceid = RangeVarGetCreationNamespace(cxt->relation);
454 			RangeVarAdjustRelationPersistence(cxt->relation, snamespaceid);
455 		}
456 		snamespace = get_namespace_name(snamespaceid);
457 		sname = ChooseRelationName(cxt->relation->relname,
458 								   column->colname,
459 								   "seq",
460 								   snamespaceid,
461 								   false);
462 	}
463 
464 	ereport(DEBUG1,
465 			(errmsg("%s will create implicit sequence \"%s\" for serial column \"%s.%s\"",
466 					cxt->stmtType, sname,
467 					cxt->relation->relname, column->colname)));
468 
469 	/*
470 	 * Build a CREATE SEQUENCE command to create the sequence object, and add
471 	 * it to the list of things to be done before this CREATE/ALTER TABLE.
472 	 */
473 	seqstmt = makeNode(CreateSeqStmt);
474 	seqstmt->for_identity = for_identity;
475 	seqstmt->sequence = makeRangeVar(snamespace, sname, -1);
476 	seqstmt->options = seqoptions;
477 
478 	/*
479 	 * If a sequence data type was specified, add it to the options.  Prepend
480 	 * to the list rather than append; in case a user supplied their own AS
481 	 * clause, the "redundant options" error will point to their occurrence,
482 	 * not our synthetic one.
483 	 */
484 	if (seqtypid)
485 		seqstmt->options = lcons(makeDefElem("as",
486 											 (Node *) makeTypeNameFromOid(seqtypid, -1),
487 											 -1),
488 								 seqstmt->options);
489 
490 	/*
491 	 * If this is ALTER ADD COLUMN, make sure the sequence will be owned by
492 	 * the table's owner.  The current user might be someone else (perhaps a
493 	 * superuser, or someone who's only a member of the owning role), but the
494 	 * SEQUENCE OWNED BY mechanisms will bleat unless table and sequence have
495 	 * exactly the same owning role.
496 	 */
497 	if (cxt->rel)
498 		seqstmt->ownerId = cxt->rel->rd_rel->relowner;
499 	else
500 		seqstmt->ownerId = InvalidOid;
501 
502 	cxt->blist = lappend(cxt->blist, seqstmt);
503 
504 	/*
505 	 * Store the identity sequence name that we decided on.  ALTER TABLE ...
506 	 * ADD COLUMN ... IDENTITY needs this so that it can fill the new column
507 	 * with values from the sequence, while the association of the sequence
508 	 * with the table is not set until after the ALTER TABLE.
509 	 */
510 	column->identitySequence = seqstmt->sequence;
511 
512 	/*
513 	 * Build an ALTER SEQUENCE ... OWNED BY command to mark the sequence as
514 	 * owned by this column, and add it to the list of things to be done after
515 	 * this CREATE/ALTER TABLE.
516 	 */
517 	altseqstmt = makeNode(AlterSeqStmt);
518 	altseqstmt->sequence = makeRangeVar(snamespace, sname, -1);
519 	attnamelist = list_make3(makeString(snamespace),
520 							 makeString(cxt->relation->relname),
521 							 makeString(column->colname));
522 	altseqstmt->options = list_make1(makeDefElem("owned_by",
523 												 (Node *) attnamelist, -1));
524 	altseqstmt->for_identity = for_identity;
525 
526 	cxt->alist = lappend(cxt->alist, altseqstmt);
527 
528 	if (snamespace_p)
529 		*snamespace_p = snamespace;
530 	if (sname_p)
531 		*sname_p = sname;
532 }
533 
534 /*
535  * transformColumnDefinition -
536  *		transform a single ColumnDef within CREATE TABLE
537  *		Also used in ALTER TABLE ADD COLUMN
538  */
539 static void
540 transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
541 {
542 	bool		is_serial;
543 	bool		saw_nullable;
544 	bool		saw_default;
545 	bool		saw_identity;
546 	ListCell   *clist;
547 
548 	cxt->columns = lappend(cxt->columns, column);
549 
550 	/* Check for SERIAL pseudo-types */
551 	is_serial = false;
552 	if (column->typeName
553 		&& list_length(column->typeName->names) == 1
554 		&& !column->typeName->pct_type)
555 	{
556 		char	   *typname = strVal(linitial(column->typeName->names));
557 
558 		if (strcmp(typname, "smallserial") == 0 ||
559 			strcmp(typname, "serial2") == 0)
560 		{
561 			is_serial = true;
562 			column->typeName->names = NIL;
563 			column->typeName->typeOid = INT2OID;
564 		}
565 		else if (strcmp(typname, "serial") == 0 ||
566 				 strcmp(typname, "serial4") == 0)
567 		{
568 			is_serial = true;
569 			column->typeName->names = NIL;
570 			column->typeName->typeOid = INT4OID;
571 		}
572 		else if (strcmp(typname, "bigserial") == 0 ||
573 				 strcmp(typname, "serial8") == 0)
574 		{
575 			is_serial = true;
576 			column->typeName->names = NIL;
577 			column->typeName->typeOid = INT8OID;
578 		}
579 
580 		/*
581 		 * We have to reject "serial[]" explicitly, because once we've set
582 		 * typeid, LookupTypeName won't notice arrayBounds.  We don't need any
583 		 * special coding for serial(typmod) though.
584 		 */
585 		if (is_serial && column->typeName->arrayBounds != NIL)
586 			ereport(ERROR,
587 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
588 					 errmsg("array of serial is not implemented"),
589 					 parser_errposition(cxt->pstate,
590 										column->typeName->location)));
591 	}
592 
593 	/* Do necessary work on the column type declaration */
594 	if (column->typeName)
595 		transformColumnType(cxt, column);
596 
597 	/* Special actions for SERIAL pseudo-types */
598 	if (is_serial)
599 	{
600 		char	   *snamespace;
601 		char	   *sname;
602 		char	   *qstring;
603 		A_Const    *snamenode;
604 		TypeCast   *castnode;
605 		FuncCall   *funccallnode;
606 		Constraint *constraint;
607 
608 		generateSerialExtraStmts(cxt, column,
609 								 column->typeName->typeOid, NIL, false,
610 								 &snamespace, &sname);
611 
612 		/*
613 		 * Create appropriate constraints for SERIAL.  We do this in full,
614 		 * rather than shortcutting, so that we will detect any conflicting
615 		 * constraints the user wrote (like a different DEFAULT).
616 		 *
617 		 * Create an expression tree representing the function call
618 		 * nextval('sequencename').  We cannot reduce the raw tree to cooked
619 		 * form until after the sequence is created, but there's no need to do
620 		 * so.
621 		 */
622 		qstring = quote_qualified_identifier(snamespace, sname);
623 		snamenode = makeNode(A_Const);
624 		snamenode->val.type = T_String;
625 		snamenode->val.val.str = qstring;
626 		snamenode->location = -1;
627 		castnode = makeNode(TypeCast);
628 		castnode->typeName = SystemTypeName("regclass");
629 		castnode->arg = (Node *) snamenode;
630 		castnode->location = -1;
631 		funccallnode = makeFuncCall(SystemFuncName("nextval"),
632 									list_make1(castnode),
633 									-1);
634 		constraint = makeNode(Constraint);
635 		constraint->contype = CONSTR_DEFAULT;
636 		constraint->location = -1;
637 		constraint->raw_expr = (Node *) funccallnode;
638 		constraint->cooked_expr = NULL;
639 		column->constraints = lappend(column->constraints, constraint);
640 
641 		constraint = makeNode(Constraint);
642 		constraint->contype = CONSTR_NOTNULL;
643 		constraint->location = -1;
644 		column->constraints = lappend(column->constraints, constraint);
645 	}
646 
647 	/* Process column constraints, if any... */
648 	transformConstraintAttrs(cxt, column->constraints);
649 
650 	saw_nullable = false;
651 	saw_default = false;
652 	saw_identity = false;
653 
654 	foreach(clist, column->constraints)
655 	{
656 		Constraint *constraint = lfirst_node(Constraint, clist);
657 
658 		switch (constraint->contype)
659 		{
660 			case CONSTR_NULL:
661 				if (saw_nullable && column->is_not_null)
662 					ereport(ERROR,
663 							(errcode(ERRCODE_SYNTAX_ERROR),
664 							 errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
665 									column->colname, cxt->relation->relname),
666 							 parser_errposition(cxt->pstate,
667 												constraint->location)));
668 				column->is_not_null = false;
669 				saw_nullable = true;
670 				break;
671 
672 			case CONSTR_NOTNULL:
673 				if (saw_nullable && !column->is_not_null)
674 					ereport(ERROR,
675 							(errcode(ERRCODE_SYNTAX_ERROR),
676 							 errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
677 									column->colname, cxt->relation->relname),
678 							 parser_errposition(cxt->pstate,
679 												constraint->location)));
680 				column->is_not_null = true;
681 				saw_nullable = true;
682 				break;
683 
684 			case CONSTR_DEFAULT:
685 				if (saw_default)
686 					ereport(ERROR,
687 							(errcode(ERRCODE_SYNTAX_ERROR),
688 							 errmsg("multiple default values specified for column \"%s\" of table \"%s\"",
689 									column->colname, cxt->relation->relname),
690 							 parser_errposition(cxt->pstate,
691 												constraint->location)));
692 				column->raw_default = constraint->raw_expr;
693 				Assert(constraint->cooked_expr == NULL);
694 				saw_default = true;
695 				break;
696 
697 			case CONSTR_IDENTITY:
698 				{
699 					Type		ctype;
700 					Oid			typeOid;
701 
702 					if (cxt->ofType)
703 						ereport(ERROR,
704 								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
705 								 errmsg("identity columns are not supported on typed tables")));
706 					if (cxt->partbound)
707 						ereport(ERROR,
708 								(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
709 								 errmsg("identity columns are not supported on partitions")));
710 
711 					ctype = typenameType(cxt->pstate, column->typeName, NULL);
712 					typeOid = HeapTupleGetOid(ctype);
713 					ReleaseSysCache(ctype);
714 
715 					if (saw_identity)
716 						ereport(ERROR,
717 								(errcode(ERRCODE_SYNTAX_ERROR),
718 								 errmsg("multiple identity specifications for column \"%s\" of table \"%s\"",
719 										column->colname, cxt->relation->relname),
720 								 parser_errposition(cxt->pstate,
721 													constraint->location)));
722 
723 					generateSerialExtraStmts(cxt, column,
724 											 typeOid, constraint->options, true,
725 											 NULL, NULL);
726 
727 					column->identity = constraint->generated_when;
728 					saw_identity = true;
729 
730 					/* An identity column is implicitly NOT NULL */
731 					if (saw_nullable && !column->is_not_null)
732 						ereport(ERROR,
733 								(errcode(ERRCODE_SYNTAX_ERROR),
734 								 errmsg("conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"",
735 										column->colname, cxt->relation->relname),
736 								 parser_errposition(cxt->pstate,
737 													constraint->location)));
738 					column->is_not_null = true;
739 					saw_nullable = true;
740 					break;
741 				}
742 
743 			case CONSTR_CHECK:
744 				cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
745 				break;
746 
747 			case CONSTR_PRIMARY:
748 				if (cxt->isforeign)
749 					ereport(ERROR,
750 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
751 							 errmsg("primary key constraints are not supported on foreign tables"),
752 							 parser_errposition(cxt->pstate,
753 												constraint->location)));
754 				/* FALL THRU */
755 
756 			case CONSTR_UNIQUE:
757 				if (cxt->isforeign)
758 					ereport(ERROR,
759 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
760 							 errmsg("unique constraints are not supported on foreign tables"),
761 							 parser_errposition(cxt->pstate,
762 												constraint->location)));
763 				if (constraint->keys == NIL)
764 					constraint->keys = list_make1(makeString(column->colname));
765 				cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
766 				break;
767 
768 			case CONSTR_EXCLUSION:
769 				/* grammar does not allow EXCLUDE as a column constraint */
770 				elog(ERROR, "column exclusion constraints are not supported");
771 				break;
772 
773 			case CONSTR_FOREIGN:
774 				if (cxt->isforeign)
775 					ereport(ERROR,
776 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
777 							 errmsg("foreign key constraints are not supported on foreign tables"),
778 							 parser_errposition(cxt->pstate,
779 												constraint->location)));
780 
781 				/*
782 				 * Fill in the current attribute's name and throw it into the
783 				 * list of FK constraints to be processed later.
784 				 */
785 				constraint->fk_attrs = list_make1(makeString(column->colname));
786 				cxt->fkconstraints = lappend(cxt->fkconstraints, constraint);
787 				break;
788 
789 			case CONSTR_ATTR_DEFERRABLE:
790 			case CONSTR_ATTR_NOT_DEFERRABLE:
791 			case CONSTR_ATTR_DEFERRED:
792 			case CONSTR_ATTR_IMMEDIATE:
793 				/* transformConstraintAttrs took care of these */
794 				break;
795 
796 			default:
797 				elog(ERROR, "unrecognized constraint type: %d",
798 					 constraint->contype);
799 				break;
800 		}
801 
802 		if (saw_default && saw_identity)
803 			ereport(ERROR,
804 					(errcode(ERRCODE_SYNTAX_ERROR),
805 					 errmsg("both default and identity specified for column \"%s\" of table \"%s\"",
806 							column->colname, cxt->relation->relname),
807 					 parser_errposition(cxt->pstate,
808 										constraint->location)));
809 	}
810 
811 	/*
812 	 * If needed, generate ALTER FOREIGN TABLE ALTER COLUMN statement to add
813 	 * per-column foreign data wrapper options to this column after creation.
814 	 */
815 	if (column->fdwoptions != NIL)
816 	{
817 		AlterTableStmt *stmt;
818 		AlterTableCmd *cmd;
819 
820 		cmd = makeNode(AlterTableCmd);
821 		cmd->subtype = AT_AlterColumnGenericOptions;
822 		cmd->name = column->colname;
823 		cmd->def = (Node *) column->fdwoptions;
824 		cmd->behavior = DROP_RESTRICT;
825 		cmd->missing_ok = false;
826 
827 		stmt = makeNode(AlterTableStmt);
828 		stmt->relation = cxt->relation;
829 		stmt->cmds = NIL;
830 		stmt->relkind = OBJECT_FOREIGN_TABLE;
831 		stmt->cmds = lappend(stmt->cmds, cmd);
832 
833 		cxt->alist = lappend(cxt->alist, stmt);
834 	}
835 }
836 
837 /*
838  * transformTableConstraint
839  *		transform a Constraint node within CREATE TABLE or ALTER TABLE
840  */
841 static void
842 transformTableConstraint(CreateStmtContext *cxt, Constraint *constraint)
843 {
844 	switch (constraint->contype)
845 	{
846 		case CONSTR_PRIMARY:
847 			if (cxt->isforeign)
848 				ereport(ERROR,
849 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
850 						 errmsg("primary key constraints are not supported on foreign tables"),
851 						 parser_errposition(cxt->pstate,
852 											constraint->location)));
853 			cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
854 			break;
855 
856 		case CONSTR_UNIQUE:
857 			if (cxt->isforeign)
858 				ereport(ERROR,
859 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
860 						 errmsg("unique constraints are not supported on foreign tables"),
861 						 parser_errposition(cxt->pstate,
862 											constraint->location)));
863 			cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
864 			break;
865 
866 		case CONSTR_EXCLUSION:
867 			if (cxt->isforeign)
868 				ereport(ERROR,
869 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
870 						 errmsg("exclusion constraints are not supported on foreign tables"),
871 						 parser_errposition(cxt->pstate,
872 											constraint->location)));
873 			if (cxt->ispartitioned)
874 				ereport(ERROR,
875 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
876 						 errmsg("exclusion constraints are not supported on partitioned tables"),
877 						 parser_errposition(cxt->pstate,
878 											constraint->location)));
879 			cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
880 			break;
881 
882 		case CONSTR_CHECK:
883 			cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
884 			break;
885 
886 		case CONSTR_FOREIGN:
887 			if (cxt->isforeign)
888 				ereport(ERROR,
889 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
890 						 errmsg("foreign key constraints are not supported on foreign tables"),
891 						 parser_errposition(cxt->pstate,
892 											constraint->location)));
893 			cxt->fkconstraints = lappend(cxt->fkconstraints, constraint);
894 			break;
895 
896 		case CONSTR_NULL:
897 		case CONSTR_NOTNULL:
898 		case CONSTR_DEFAULT:
899 		case CONSTR_ATTR_DEFERRABLE:
900 		case CONSTR_ATTR_NOT_DEFERRABLE:
901 		case CONSTR_ATTR_DEFERRED:
902 		case CONSTR_ATTR_IMMEDIATE:
903 			elog(ERROR, "invalid context for constraint type %d",
904 				 constraint->contype);
905 			break;
906 
907 		default:
908 			elog(ERROR, "unrecognized constraint type: %d",
909 				 constraint->contype);
910 			break;
911 	}
912 }
913 
914 /*
915  * transformTableLikeClause
916  *
917  * Change the LIKE <srctable> portion of a CREATE TABLE statement into
918  * column definitions that recreate the user defined column portions of
919  * <srctable>.  Also, if there are any LIKE options that we can't fully
920  * process at this point, add the TableLikeClause to cxt->likeclauses, which
921  * will cause utility.c to call expandTableLikeClause() after the new
922  * table has been created.
923  */
924 static void
925 transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_clause)
926 {
927 	AttrNumber	parent_attno;
928 	Relation	relation;
929 	TupleDesc	tupleDesc;
930 	TupleConstr *constr;
931 	AclResult	aclresult;
932 	char	   *comment;
933 	ParseCallbackState pcbstate;
934 
935 	setup_parser_errposition_callback(&pcbstate, cxt->pstate,
936 									  table_like_clause->relation->location);
937 
938 	/* we could support LIKE in many cases, but worry about it another day */
939 	if (cxt->isforeign)
940 		ereport(ERROR,
941 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
942 				 errmsg("LIKE is not supported for creating foreign tables")));
943 
944 	/* Open the relation referenced by the LIKE clause */
945 	relation = relation_openrv(table_like_clause->relation, AccessShareLock);
946 
947 	if (relation->rd_rel->relkind != RELKIND_RELATION &&
948 		relation->rd_rel->relkind != RELKIND_VIEW &&
949 		relation->rd_rel->relkind != RELKIND_MATVIEW &&
950 		relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
951 		relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
952 		relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
953 		ereport(ERROR,
954 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
955 				 errmsg("\"%s\" is not a table, view, materialized view, composite type, or foreign table",
956 						RelationGetRelationName(relation))));
957 
958 	cancel_parser_errposition_callback(&pcbstate);
959 
960 	/*
961 	 * Check for privileges
962 	 */
963 	if (relation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
964 	{
965 		aclresult = pg_type_aclcheck(relation->rd_rel->reltype, GetUserId(),
966 									 ACL_USAGE);
967 		if (aclresult != ACLCHECK_OK)
968 			aclcheck_error(aclresult, OBJECT_TYPE,
969 						   RelationGetRelationName(relation));
970 	}
971 	else
972 	{
973 		aclresult = pg_class_aclcheck(RelationGetRelid(relation), GetUserId(),
974 									  ACL_SELECT);
975 		if (aclresult != ACLCHECK_OK)
976 			aclcheck_error(aclresult, get_relkind_objtype(relation->rd_rel->relkind),
977 						   RelationGetRelationName(relation));
978 	}
979 
980 	tupleDesc = RelationGetDescr(relation);
981 	constr = tupleDesc->constr;
982 
983 	/*
984 	 * Insert the copied attributes into the cxt for the new table definition.
985 	 * We must do this now so that they appear in the table in the relative
986 	 * position where the LIKE clause is, as required by SQL99.
987 	 */
988 	for (parent_attno = 1; parent_attno <= tupleDesc->natts;
989 		 parent_attno++)
990 	{
991 		Form_pg_attribute attribute = TupleDescAttr(tupleDesc,
992 													parent_attno - 1);
993 		char	   *attributeName = NameStr(attribute->attname);
994 		ColumnDef  *def;
995 
996 		/*
997 		 * Ignore dropped columns in the parent.
998 		 */
999 		if (attribute->attisdropped)
1000 			continue;
1001 
1002 		/*
1003 		 * Create a new column, which is marked as NOT inherited.
1004 		 *
1005 		 * For constraints, ONLY the NOT NULL constraint is inherited by the
1006 		 * new column definition per SQL99.
1007 		 */
1008 		def = makeNode(ColumnDef);
1009 		def->colname = pstrdup(attributeName);
1010 		def->typeName = makeTypeNameFromOid(attribute->atttypid,
1011 											attribute->atttypmod);
1012 		def->inhcount = 0;
1013 		def->is_local = true;
1014 		def->is_not_null = attribute->attnotnull;
1015 		def->is_from_type = false;
1016 		def->storage = 0;
1017 		def->raw_default = NULL;
1018 		def->cooked_default = NULL;
1019 		def->collClause = NULL;
1020 		def->collOid = attribute->attcollation;
1021 		def->constraints = NIL;
1022 		def->location = -1;
1023 
1024 		/*
1025 		 * Add to column list
1026 		 */
1027 		cxt->columns = lappend(cxt->columns, def);
1028 
1029 		/*
1030 		 * Copy default, if present and the default has been requested
1031 		 */
1032 		if (attribute->atthasdef &&
1033 			(table_like_clause->options & CREATE_TABLE_LIKE_DEFAULTS))
1034 		{
1035 			Node	   *this_default = NULL;
1036 			AttrDefault *attrdef;
1037 			int			i;
1038 
1039 			/* Find default in constraint structure */
1040 			Assert(constr != NULL);
1041 			attrdef = constr->defval;
1042 			for (i = 0; i < constr->num_defval; i++)
1043 			{
1044 				if (attrdef[i].adnum == parent_attno)
1045 				{
1046 					this_default = stringToNode(attrdef[i].adbin);
1047 					break;
1048 				}
1049 			}
1050 			Assert(this_default != NULL);
1051 
1052 			/*
1053 			 * If default expr could contain any vars, we'd need to fix 'em,
1054 			 * but it can't; so default is ready to apply to child.
1055 			 */
1056 
1057 			def->cooked_default = this_default;
1058 		}
1059 
1060 		/*
1061 		 * Copy identity if requested
1062 		 */
1063 		if (attribute->attidentity &&
1064 			(table_like_clause->options & CREATE_TABLE_LIKE_IDENTITY))
1065 		{
1066 			Oid			seq_relid;
1067 			List	   *seq_options;
1068 
1069 			/*
1070 			 * find sequence owned by old column; extract sequence parameters;
1071 			 * build new create sequence command
1072 			 */
1073 			seq_relid = getOwnedSequence(RelationGetRelid(relation), attribute->attnum);
1074 			seq_options = sequence_options(seq_relid);
1075 			generateSerialExtraStmts(cxt, def,
1076 									 InvalidOid, seq_options, true,
1077 									 NULL, NULL);
1078 			def->identity = attribute->attidentity;
1079 		}
1080 
1081 		/* Likewise, copy storage if requested */
1082 		if (table_like_clause->options & CREATE_TABLE_LIKE_STORAGE)
1083 			def->storage = attribute->attstorage;
1084 		else
1085 			def->storage = 0;
1086 
1087 		/* Likewise, copy comment if requested */
1088 		if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) &&
1089 			(comment = GetComment(attribute->attrelid,
1090 								  RelationRelationId,
1091 								  attribute->attnum)) != NULL)
1092 		{
1093 			CommentStmt *stmt = makeNode(CommentStmt);
1094 
1095 			stmt->objtype = OBJECT_COLUMN;
1096 			stmt->object = (Node *) list_make3(makeString(cxt->relation->schemaname),
1097 											   makeString(cxt->relation->relname),
1098 											   makeString(def->colname));
1099 			stmt->comment = comment;
1100 
1101 			cxt->alist = lappend(cxt->alist, stmt);
1102 		}
1103 	}
1104 
1105 	/* We use oids if at least one LIKE'ed table has oids. */
1106 	cxt->hasoids |= relation->rd_rel->relhasoids;
1107 
1108 	/*
1109 	 * We cannot yet deal with CHECK constraints or indexes, since we don't
1110 	 * yet know what column numbers the copied columns will have in the
1111 	 * finished table.  If any of those options are specified, add the LIKE
1112 	 * clause to cxt->likeclauses so that expandTableLikeClause will be called
1113 	 * after we do know that.  Also, remember the relation OID so that
1114 	 * expandTableLikeClause is certain to open the same table.
1115 	 */
1116 	if (table_like_clause->options &
1117 		(CREATE_TABLE_LIKE_CONSTRAINTS |
1118 		 CREATE_TABLE_LIKE_INDEXES))
1119 	{
1120 		table_like_clause->relationOid = RelationGetRelid(relation);
1121 		cxt->likeclauses = lappend(cxt->likeclauses, table_like_clause);
1122 	}
1123 
1124 	/*
1125 	 * We may copy extended statistics if requested, since the representation
1126 	 * of CreateStatsStmt doesn't depend on column numbers.
1127 	 */
1128 	if (table_like_clause->options & CREATE_TABLE_LIKE_STATISTICS)
1129 	{
1130 		List	   *parent_extstats;
1131 		ListCell   *l;
1132 
1133 		parent_extstats = RelationGetStatExtList(relation);
1134 
1135 		foreach(l, parent_extstats)
1136 		{
1137 			Oid			parent_stat_oid = lfirst_oid(l);
1138 			CreateStatsStmt *stats_stmt;
1139 
1140 			stats_stmt = generateClonedExtStatsStmt(cxt->relation,
1141 													RelationGetRelid(relation),
1142 													parent_stat_oid);
1143 
1144 			/* Copy comment on statistics object, if requested */
1145 			if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS)
1146 			{
1147 				comment = GetComment(parent_stat_oid, StatisticExtRelationId, 0);
1148 
1149 				/*
1150 				 * We make use of CreateStatsStmt's stxcomment option, so as
1151 				 * not to need to know now what name the statistics will have.
1152 				 */
1153 				stats_stmt->stxcomment = comment;
1154 			}
1155 
1156 			cxt->extstats = lappend(cxt->extstats, stats_stmt);
1157 		}
1158 
1159 		list_free(parent_extstats);
1160 	}
1161 
1162 	/*
1163 	 * Close the parent rel, but keep our AccessShareLock on it until xact
1164 	 * commit.  That will prevent someone else from deleting or ALTERing the
1165 	 * parent before we can run expandTableLikeClause.
1166 	 */
1167 	heap_close(relation, NoLock);
1168 }
1169 
1170 /*
1171  * expandTableLikeClause
1172  *
1173  * Process LIKE options that require knowing the final column numbers
1174  * assigned to the new table's columns.  This executes after we have
1175  * run DefineRelation for the new table.  It returns a list of utility
1176  * commands that should be run to generate indexes etc.
1177  */
1178 List *
1179 expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
1180 {
1181 	List	   *result = NIL;
1182 	List	   *atsubcmds = NIL;
1183 	Relation	relation;
1184 	Relation	childrel;
1185 	TupleDesc	tupleDesc;
1186 	TupleConstr *constr;
1187 	AttrNumber *attmap;
1188 	char	   *comment;
1189 
1190 	/*
1191 	 * Open the relation referenced by the LIKE clause.  We should still have
1192 	 * the table lock obtained by transformTableLikeClause (and this'll throw
1193 	 * an assertion failure if not).  Hence, no need to recheck privileges
1194 	 * etc.  We must open the rel by OID not name, to be sure we get the same
1195 	 * table.
1196 	 */
1197 	if (!OidIsValid(table_like_clause->relationOid))
1198 		elog(ERROR, "expandTableLikeClause called on untransformed LIKE clause");
1199 
1200 	relation = relation_open(table_like_clause->relationOid, NoLock);
1201 
1202 	tupleDesc = RelationGetDescr(relation);
1203 	constr = tupleDesc->constr;
1204 
1205 	/*
1206 	 * Open the newly-created child relation; we have lock on that too.
1207 	 */
1208 	childrel = relation_openrv(heapRel, NoLock);
1209 
1210 	/*
1211 	 * Construct a map from the LIKE relation's attnos to the child rel's.
1212 	 * This re-checks type match etc, although it shouldn't be possible to
1213 	 * have a failure since both tables are locked.
1214 	 */
1215 	attmap = convert_tuples_by_name_map(RelationGetDescr(childrel),
1216 										tupleDesc,
1217 										gettext_noop("could not convert row type"));
1218 
1219 	/*
1220 	 * Copy CHECK constraints if requested, being careful to adjust attribute
1221 	 * numbers so they match the child.
1222 	 */
1223 	if ((table_like_clause->options & CREATE_TABLE_LIKE_CONSTRAINTS) &&
1224 		constr != NULL)
1225 	{
1226 		int			ccnum;
1227 
1228 		for (ccnum = 0; ccnum < constr->num_check; ccnum++)
1229 		{
1230 			char	   *ccname = constr->check[ccnum].ccname;
1231 			char	   *ccbin = constr->check[ccnum].ccbin;
1232 			Node	   *ccbin_node;
1233 			bool		found_whole_row;
1234 			Constraint *n;
1235 			AlterTableCmd *atsubcmd;
1236 
1237 			ccbin_node = map_variable_attnos(stringToNode(ccbin),
1238 											 1, 0,
1239 											 attmap, tupleDesc->natts,
1240 											 InvalidOid, &found_whole_row);
1241 
1242 			/*
1243 			 * We reject whole-row variables because the whole point of LIKE
1244 			 * is that the new table's rowtype might later diverge from the
1245 			 * parent's.  So, while translation might be possible right now,
1246 			 * it wouldn't be possible to guarantee it would work in future.
1247 			 */
1248 			if (found_whole_row)
1249 				ereport(ERROR,
1250 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1251 						 errmsg("cannot convert whole-row table reference"),
1252 						 errdetail("Constraint \"%s\" contains a whole-row reference to table \"%s\".",
1253 								   ccname,
1254 								   RelationGetRelationName(relation))));
1255 
1256 			n = makeNode(Constraint);
1257 			n->contype = CONSTR_CHECK;
1258 			n->location = -1;
1259 			n->conname = pstrdup(ccname);
1260 			n->raw_expr = NULL;
1261 			n->cooked_expr = nodeToString(ccbin_node);
1262 
1263 			/* We can skip validation, since the new table should be empty. */
1264 			n->skip_validation = true;
1265 			n->initially_valid = true;
1266 
1267 			atsubcmd = makeNode(AlterTableCmd);
1268 			atsubcmd->subtype = AT_AddConstraint;
1269 			atsubcmd->def = (Node *) n;
1270 			atsubcmds = lappend(atsubcmds, atsubcmd);
1271 
1272 			/* Copy comment on constraint */
1273 			if ((table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) &&
1274 				(comment = GetComment(get_relation_constraint_oid(RelationGetRelid(relation),
1275 																  n->conname, false),
1276 									  ConstraintRelationId,
1277 									  0)) != NULL)
1278 			{
1279 				CommentStmt *stmt = makeNode(CommentStmt);
1280 
1281 				stmt->objtype = OBJECT_TABCONSTRAINT;
1282 				stmt->object = (Node *) list_make3(makeString(heapRel->schemaname),
1283 												   makeString(heapRel->relname),
1284 												   makeString(n->conname));
1285 				stmt->comment = comment;
1286 
1287 				result = lappend(result, stmt);
1288 			}
1289 		}
1290 	}
1291 
1292 	/*
1293 	 * If we generated any ALTER TABLE actions above, wrap them into a single
1294 	 * ALTER TABLE command.  Stick it at the front of the result, so it runs
1295 	 * before any CommentStmts we made above.
1296 	 */
1297 	if (atsubcmds)
1298 	{
1299 		AlterTableStmt *atcmd = makeNode(AlterTableStmt);
1300 
1301 		atcmd->relation = copyObject(heapRel);
1302 		atcmd->cmds = atsubcmds;
1303 		atcmd->relkind = OBJECT_TABLE;
1304 		atcmd->missing_ok = false;
1305 		result = lcons(atcmd, result);
1306 	}
1307 
1308 	/*
1309 	 * Process indexes if required.
1310 	 */
1311 	if ((table_like_clause->options & CREATE_TABLE_LIKE_INDEXES) &&
1312 		relation->rd_rel->relhasindex)
1313 	{
1314 		List	   *parent_indexes;
1315 		ListCell   *l;
1316 
1317 		parent_indexes = RelationGetIndexList(relation);
1318 
1319 		foreach(l, parent_indexes)
1320 		{
1321 			Oid			parent_index_oid = lfirst_oid(l);
1322 			Relation	parent_index;
1323 			IndexStmt  *index_stmt;
1324 
1325 			parent_index = index_open(parent_index_oid, AccessShareLock);
1326 
1327 			/* Build CREATE INDEX statement to recreate the parent_index */
1328 			index_stmt = generateClonedIndexStmt(heapRel, InvalidOid,
1329 												 parent_index,
1330 												 attmap, tupleDesc->natts, NULL);
1331 
1332 			/* Copy comment on index, if requested */
1333 			if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS)
1334 			{
1335 				comment = GetComment(parent_index_oid, RelationRelationId, 0);
1336 
1337 				/*
1338 				 * We make use of IndexStmt's idxcomment option, so as not to
1339 				 * need to know now what name the index will have.
1340 				 */
1341 				index_stmt->idxcomment = comment;
1342 			}
1343 
1344 			result = lappend(result, index_stmt);
1345 
1346 			index_close(parent_index, AccessShareLock);
1347 		}
1348 	}
1349 
1350 	/* Done with child rel */
1351 	heap_close(childrel, NoLock);
1352 
1353 	/*
1354 	 * Close the parent rel, but keep our AccessShareLock on it until xact
1355 	 * commit.  That will prevent someone else from deleting or ALTERing the
1356 	 * parent before the child is committed.
1357 	 */
1358 	heap_close(relation, NoLock);
1359 
1360 	return result;
1361 }
1362 
1363 static void
1364 transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
1365 {
1366 	HeapTuple	tuple;
1367 	TupleDesc	tupdesc;
1368 	int			i;
1369 	Oid			ofTypeId;
1370 
1371 	AssertArg(ofTypename);
1372 
1373 	tuple = typenameType(NULL, ofTypename, NULL);
1374 	check_of_type(tuple);
1375 	ofTypeId = HeapTupleGetOid(tuple);
1376 	ofTypename->typeOid = ofTypeId; /* cached for later */
1377 
1378 	tupdesc = lookup_rowtype_tupdesc(ofTypeId, -1);
1379 	for (i = 0; i < tupdesc->natts; i++)
1380 	{
1381 		Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
1382 		ColumnDef  *n;
1383 
1384 		if (attr->attisdropped)
1385 			continue;
1386 
1387 		n = makeNode(ColumnDef);
1388 		n->colname = pstrdup(NameStr(attr->attname));
1389 		n->typeName = makeTypeNameFromOid(attr->atttypid, attr->atttypmod);
1390 		n->inhcount = 0;
1391 		n->is_local = true;
1392 		n->is_not_null = false;
1393 		n->is_from_type = true;
1394 		n->storage = 0;
1395 		n->raw_default = NULL;
1396 		n->cooked_default = NULL;
1397 		n->collClause = NULL;
1398 		n->collOid = attr->attcollation;
1399 		n->constraints = NIL;
1400 		n->location = -1;
1401 		cxt->columns = lappend(cxt->columns, n);
1402 	}
1403 	DecrTupleDescRefCount(tupdesc);
1404 
1405 	ReleaseSysCache(tuple);
1406 }
1407 
1408 /*
1409  * Generate an IndexStmt node using information from an already existing index
1410  * "source_idx", for the rel identified either by heapRel or heapRelid.
1411  *
1412  * Attribute numbers should be adjusted according to attmap.
1413  */
1414 IndexStmt *
1415 generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx,
1416 						const AttrNumber *attmap, int attmap_length, Oid *constraintOid)
1417 {
1418 	Oid			source_relid = RelationGetRelid(source_idx);
1419 	HeapTuple	ht_idxrel;
1420 	HeapTuple	ht_idx;
1421 	HeapTuple	ht_am;
1422 	Form_pg_class idxrelrec;
1423 	Form_pg_index idxrec;
1424 	Form_pg_am	amrec;
1425 	oidvector  *indcollation;
1426 	oidvector  *indclass;
1427 	IndexStmt  *index;
1428 	List	   *indexprs;
1429 	ListCell   *indexpr_item;
1430 	Oid			indrelid;
1431 	int			keyno;
1432 	Oid			keycoltype;
1433 	Datum		datum;
1434 	bool		isnull;
1435 
1436 	Assert((heapRel == NULL && OidIsValid(heapRelid)) ||
1437 		   (heapRel != NULL && !OidIsValid(heapRelid)));
1438 
1439 	/*
1440 	 * Fetch pg_class tuple of source index.  We can't use the copy in the
1441 	 * relcache entry because it doesn't include optional fields.
1442 	 */
1443 	ht_idxrel = SearchSysCache1(RELOID, ObjectIdGetDatum(source_relid));
1444 	if (!HeapTupleIsValid(ht_idxrel))
1445 		elog(ERROR, "cache lookup failed for relation %u", source_relid);
1446 	idxrelrec = (Form_pg_class) GETSTRUCT(ht_idxrel);
1447 
1448 	/* Fetch pg_index tuple for source index from relcache entry */
1449 	ht_idx = source_idx->rd_indextuple;
1450 	idxrec = (Form_pg_index) GETSTRUCT(ht_idx);
1451 	indrelid = idxrec->indrelid;
1452 
1453 	/* Fetch the pg_am tuple of the index' access method */
1454 	ht_am = SearchSysCache1(AMOID, ObjectIdGetDatum(idxrelrec->relam));
1455 	if (!HeapTupleIsValid(ht_am))
1456 		elog(ERROR, "cache lookup failed for access method %u",
1457 			 idxrelrec->relam);
1458 	amrec = (Form_pg_am) GETSTRUCT(ht_am);
1459 
1460 	/* Extract indcollation from the pg_index tuple */
1461 	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
1462 							Anum_pg_index_indcollation, &isnull);
1463 	Assert(!isnull);
1464 	indcollation = (oidvector *) DatumGetPointer(datum);
1465 
1466 	/* Extract indclass from the pg_index tuple */
1467 	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
1468 							Anum_pg_index_indclass, &isnull);
1469 	Assert(!isnull);
1470 	indclass = (oidvector *) DatumGetPointer(datum);
1471 
1472 	/* Begin building the IndexStmt */
1473 	index = makeNode(IndexStmt);
1474 	index->relation = heapRel;
1475 	index->relationId = heapRelid;
1476 	index->accessMethod = pstrdup(NameStr(amrec->amname));
1477 	if (OidIsValid(idxrelrec->reltablespace))
1478 		index->tableSpace = get_tablespace_name(idxrelrec->reltablespace);
1479 	else
1480 		index->tableSpace = NULL;
1481 	index->excludeOpNames = NIL;
1482 	index->idxcomment = NULL;
1483 	index->indexOid = InvalidOid;
1484 	index->oldNode = InvalidOid;
1485 	index->unique = idxrec->indisunique;
1486 	index->primary = idxrec->indisprimary;
1487 	index->transformed = true;	/* don't need transformIndexStmt */
1488 	index->concurrent = false;
1489 	index->if_not_exists = false;
1490 
1491 	/*
1492 	 * We don't try to preserve the name of the source index; instead, just
1493 	 * let DefineIndex() choose a reasonable name.  (If we tried to preserve
1494 	 * the name, we'd get duplicate-relation-name failures unless the source
1495 	 * table was in a different schema.)
1496 	 */
1497 	index->idxname = NULL;
1498 
1499 	/*
1500 	 * If the index is marked PRIMARY or has an exclusion condition, it's
1501 	 * certainly from a constraint; else, if it's not marked UNIQUE, it
1502 	 * certainly isn't.  If it is or might be from a constraint, we have to
1503 	 * fetch the pg_constraint record.
1504 	 */
1505 	if (index->primary || index->unique || idxrec->indisexclusion)
1506 	{
1507 		Oid			constraintId = get_index_constraint(source_relid);
1508 
1509 		if (OidIsValid(constraintId))
1510 		{
1511 			HeapTuple	ht_constr;
1512 			Form_pg_constraint conrec;
1513 
1514 			if (constraintOid)
1515 				*constraintOid = constraintId;
1516 
1517 			ht_constr = SearchSysCache1(CONSTROID,
1518 										ObjectIdGetDatum(constraintId));
1519 			if (!HeapTupleIsValid(ht_constr))
1520 				elog(ERROR, "cache lookup failed for constraint %u",
1521 					 constraintId);
1522 			conrec = (Form_pg_constraint) GETSTRUCT(ht_constr);
1523 
1524 			index->isconstraint = true;
1525 			index->deferrable = conrec->condeferrable;
1526 			index->initdeferred = conrec->condeferred;
1527 
1528 			/* If it's an exclusion constraint, we need the operator names */
1529 			if (idxrec->indisexclusion)
1530 			{
1531 				Datum	   *elems;
1532 				int			nElems;
1533 				int			i;
1534 
1535 				Assert(conrec->contype == CONSTRAINT_EXCLUSION);
1536 				/* Extract operator OIDs from the pg_constraint tuple */
1537 				datum = SysCacheGetAttr(CONSTROID, ht_constr,
1538 										Anum_pg_constraint_conexclop,
1539 										&isnull);
1540 				if (isnull)
1541 					elog(ERROR, "null conexclop for constraint %u",
1542 						 constraintId);
1543 
1544 				deconstruct_array(DatumGetArrayTypeP(datum),
1545 								  OIDOID, sizeof(Oid), true, 'i',
1546 								  &elems, NULL, &nElems);
1547 
1548 				for (i = 0; i < nElems; i++)
1549 				{
1550 					Oid			operid = DatumGetObjectId(elems[i]);
1551 					HeapTuple	opertup;
1552 					Form_pg_operator operform;
1553 					char	   *oprname;
1554 					char	   *nspname;
1555 					List	   *namelist;
1556 
1557 					opertup = SearchSysCache1(OPEROID,
1558 											  ObjectIdGetDatum(operid));
1559 					if (!HeapTupleIsValid(opertup))
1560 						elog(ERROR, "cache lookup failed for operator %u",
1561 							 operid);
1562 					operform = (Form_pg_operator) GETSTRUCT(opertup);
1563 					oprname = pstrdup(NameStr(operform->oprname));
1564 					/* For simplicity we always schema-qualify the op name */
1565 					nspname = get_namespace_name(operform->oprnamespace);
1566 					namelist = list_make2(makeString(nspname),
1567 										  makeString(oprname));
1568 					index->excludeOpNames = lappend(index->excludeOpNames,
1569 													namelist);
1570 					ReleaseSysCache(opertup);
1571 				}
1572 			}
1573 
1574 			ReleaseSysCache(ht_constr);
1575 		}
1576 		else
1577 			index->isconstraint = false;
1578 	}
1579 	else
1580 		index->isconstraint = false;
1581 
1582 	/* Get the index expressions, if any */
1583 	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
1584 							Anum_pg_index_indexprs, &isnull);
1585 	if (!isnull)
1586 	{
1587 		char	   *exprsString;
1588 
1589 		exprsString = TextDatumGetCString(datum);
1590 		indexprs = (List *) stringToNode(exprsString);
1591 	}
1592 	else
1593 		indexprs = NIL;
1594 
1595 	/* Build the list of IndexElem */
1596 	index->indexParams = NIL;
1597 	index->indexIncludingParams = NIL;
1598 
1599 	indexpr_item = list_head(indexprs);
1600 	for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++)
1601 	{
1602 		IndexElem  *iparam;
1603 		AttrNumber	attnum = idxrec->indkey.values[keyno];
1604 		Form_pg_attribute attr = TupleDescAttr(RelationGetDescr(source_idx),
1605 											   keyno);
1606 		int16		opt = source_idx->rd_indoption[keyno];
1607 
1608 		iparam = makeNode(IndexElem);
1609 
1610 		if (AttributeNumberIsValid(attnum))
1611 		{
1612 			/* Simple index column */
1613 			char	   *attname;
1614 
1615 			attname = get_attname(indrelid, attnum, false);
1616 			keycoltype = get_atttype(indrelid, attnum);
1617 
1618 			iparam->name = attname;
1619 			iparam->expr = NULL;
1620 		}
1621 		else
1622 		{
1623 			/* Expressional index */
1624 			Node	   *indexkey;
1625 			bool		found_whole_row;
1626 
1627 			if (indexpr_item == NULL)
1628 				elog(ERROR, "too few entries in indexprs list");
1629 			indexkey = (Node *) lfirst(indexpr_item);
1630 			indexpr_item = lnext(indexpr_item);
1631 
1632 			/* Adjust Vars to match new table's column numbering */
1633 			indexkey = map_variable_attnos(indexkey,
1634 										   1, 0,
1635 										   attmap, attmap_length,
1636 										   InvalidOid, &found_whole_row);
1637 
1638 			/* As in transformTableLikeClause, reject whole-row variables */
1639 			if (found_whole_row)
1640 				ereport(ERROR,
1641 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1642 						 errmsg("cannot convert whole-row table reference"),
1643 						 errdetail("Index \"%s\" contains a whole-row table reference.",
1644 								   RelationGetRelationName(source_idx))));
1645 
1646 			iparam->name = NULL;
1647 			iparam->expr = indexkey;
1648 
1649 			keycoltype = exprType(indexkey);
1650 		}
1651 
1652 		/* Copy the original index column name */
1653 		iparam->indexcolname = pstrdup(NameStr(attr->attname));
1654 
1655 		/* Add the collation name, if non-default */
1656 		iparam->collation = get_collation(indcollation->values[keyno], keycoltype);
1657 
1658 		/* Add the operator class name, if non-default */
1659 		iparam->opclass = get_opclass(indclass->values[keyno], keycoltype);
1660 
1661 		iparam->ordering = SORTBY_DEFAULT;
1662 		iparam->nulls_ordering = SORTBY_NULLS_DEFAULT;
1663 
1664 		/* Adjust options if necessary */
1665 		if (source_idx->rd_amroutine->amcanorder)
1666 		{
1667 			/*
1668 			 * If it supports sort ordering, copy DESC and NULLS opts. Don't
1669 			 * set non-default settings unnecessarily, though, so as to
1670 			 * improve the chance of recognizing equivalence to constraint
1671 			 * indexes.
1672 			 */
1673 			if (opt & INDOPTION_DESC)
1674 			{
1675 				iparam->ordering = SORTBY_DESC;
1676 				if ((opt & INDOPTION_NULLS_FIRST) == 0)
1677 					iparam->nulls_ordering = SORTBY_NULLS_LAST;
1678 			}
1679 			else
1680 			{
1681 				if (opt & INDOPTION_NULLS_FIRST)
1682 					iparam->nulls_ordering = SORTBY_NULLS_FIRST;
1683 			}
1684 		}
1685 
1686 		index->indexParams = lappend(index->indexParams, iparam);
1687 	}
1688 
1689 	/* Handle included columns separately */
1690 	for (keyno = idxrec->indnkeyatts; keyno < idxrec->indnatts; keyno++)
1691 	{
1692 		IndexElem  *iparam;
1693 		AttrNumber	attnum = idxrec->indkey.values[keyno];
1694 		Form_pg_attribute attr = TupleDescAttr(RelationGetDescr(source_idx),
1695 											   keyno);
1696 
1697 		iparam = makeNode(IndexElem);
1698 
1699 		if (AttributeNumberIsValid(attnum))
1700 		{
1701 			/* Simple index column */
1702 			char	   *attname;
1703 
1704 			attname = get_attname(indrelid, attnum, false);
1705 			keycoltype = get_atttype(indrelid, attnum);
1706 
1707 			iparam->name = attname;
1708 			iparam->expr = NULL;
1709 		}
1710 		else
1711 			ereport(ERROR,
1712 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1713 					 errmsg("expressions are not supported in included columns")));
1714 
1715 		/* Copy the original index column name */
1716 		iparam->indexcolname = pstrdup(NameStr(attr->attname));
1717 
1718 		index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
1719 	}
1720 	/* Copy reloptions if any */
1721 	datum = SysCacheGetAttr(RELOID, ht_idxrel,
1722 							Anum_pg_class_reloptions, &isnull);
1723 	if (!isnull)
1724 		index->options = untransformRelOptions(datum);
1725 
1726 	/* If it's a partial index, decompile and append the predicate */
1727 	datum = SysCacheGetAttr(INDEXRELID, ht_idx,
1728 							Anum_pg_index_indpred, &isnull);
1729 	if (!isnull)
1730 	{
1731 		char	   *pred_str;
1732 		Node	   *pred_tree;
1733 		bool		found_whole_row;
1734 
1735 		/* Convert text string to node tree */
1736 		pred_str = TextDatumGetCString(datum);
1737 		pred_tree = (Node *) stringToNode(pred_str);
1738 
1739 		/* Adjust Vars to match new table's column numbering */
1740 		pred_tree = map_variable_attnos(pred_tree,
1741 										1, 0,
1742 										attmap, attmap_length,
1743 										InvalidOid, &found_whole_row);
1744 
1745 		/* As in transformTableLikeClause, reject whole-row variables */
1746 		if (found_whole_row)
1747 			ereport(ERROR,
1748 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1749 					 errmsg("cannot convert whole-row table reference"),
1750 					 errdetail("Index \"%s\" contains a whole-row table reference.",
1751 							   RelationGetRelationName(source_idx))));
1752 
1753 		index->whereClause = pred_tree;
1754 	}
1755 
1756 	/* Clean up */
1757 	ReleaseSysCache(ht_idxrel);
1758 	ReleaseSysCache(ht_am);
1759 
1760 	return index;
1761 }
1762 
1763 /*
1764  * Generate a CreateStatsStmt node using information from an already existing
1765  * extended statistic "source_statsid", for the rel identified by heapRel and
1766  * heapRelid.
1767  */
1768 static CreateStatsStmt *
1769 generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid,
1770 						   Oid source_statsid)
1771 {
1772 	HeapTuple	ht_stats;
1773 	Form_pg_statistic_ext statsrec;
1774 	CreateStatsStmt *stats;
1775 	List	   *stat_types = NIL;
1776 	List	   *def_names = NIL;
1777 	bool		isnull;
1778 	Datum		datum;
1779 	ArrayType  *arr;
1780 	char	   *enabled;
1781 	int			i;
1782 
1783 	Assert(OidIsValid(heapRelid));
1784 	Assert(heapRel != NULL);
1785 
1786 	/*
1787 	 * Fetch pg_statistic_ext tuple of source statistics object.
1788 	 */
1789 	ht_stats = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(source_statsid));
1790 	if (!HeapTupleIsValid(ht_stats))
1791 		elog(ERROR, "cache lookup failed for statistics object %u", source_statsid);
1792 	statsrec = (Form_pg_statistic_ext) GETSTRUCT(ht_stats);
1793 
1794 	/* Determine which statistics types exist */
1795 	datum = SysCacheGetAttr(STATEXTOID, ht_stats,
1796 							Anum_pg_statistic_ext_stxkind, &isnull);
1797 	Assert(!isnull);
1798 	arr = DatumGetArrayTypeP(datum);
1799 	if (ARR_NDIM(arr) != 1 ||
1800 		ARR_HASNULL(arr) ||
1801 		ARR_ELEMTYPE(arr) != CHAROID)
1802 		elog(ERROR, "stxkind is not a 1-D char array");
1803 	enabled = (char *) ARR_DATA_PTR(arr);
1804 	for (i = 0; i < ARR_DIMS(arr)[0]; i++)
1805 	{
1806 		if (enabled[i] == STATS_EXT_NDISTINCT)
1807 			stat_types = lappend(stat_types, makeString("ndistinct"));
1808 		else if (enabled[i] == STATS_EXT_DEPENDENCIES)
1809 			stat_types = lappend(stat_types, makeString("dependencies"));
1810 		else
1811 			elog(ERROR, "unrecognized statistics kind %c", enabled[i]);
1812 	}
1813 
1814 	/* Determine which columns the statistics are on */
1815 	for (i = 0; i < statsrec->stxkeys.dim1; i++)
1816 	{
1817 		ColumnRef  *cref = makeNode(ColumnRef);
1818 		AttrNumber	attnum = statsrec->stxkeys.values[i];
1819 
1820 		cref->fields = list_make1(makeString(get_attname(heapRelid,
1821 														 attnum, false)));
1822 		cref->location = -1;
1823 
1824 		def_names = lappend(def_names, cref);
1825 	}
1826 
1827 	/* finally, build the output node */
1828 	stats = makeNode(CreateStatsStmt);
1829 	stats->defnames = NULL;
1830 	stats->stat_types = stat_types;
1831 	stats->exprs = def_names;
1832 	stats->relations = list_make1(heapRel);
1833 	stats->stxcomment = NULL;
1834 	stats->if_not_exists = false;
1835 
1836 	/* Clean up */
1837 	ReleaseSysCache(ht_stats);
1838 
1839 	return stats;
1840 }
1841 
1842 /*
1843  * get_collation		- fetch qualified name of a collation
1844  *
1845  * If collation is InvalidOid or is the default for the given actual_datatype,
1846  * then the return value is NIL.
1847  */
1848 static List *
1849 get_collation(Oid collation, Oid actual_datatype)
1850 {
1851 	List	   *result;
1852 	HeapTuple	ht_coll;
1853 	Form_pg_collation coll_rec;
1854 	char	   *nsp_name;
1855 	char	   *coll_name;
1856 
1857 	if (!OidIsValid(collation))
1858 		return NIL;				/* easy case */
1859 	if (collation == get_typcollation(actual_datatype))
1860 		return NIL;				/* just let it default */
1861 
1862 	ht_coll = SearchSysCache1(COLLOID, ObjectIdGetDatum(collation));
1863 	if (!HeapTupleIsValid(ht_coll))
1864 		elog(ERROR, "cache lookup failed for collation %u", collation);
1865 	coll_rec = (Form_pg_collation) GETSTRUCT(ht_coll);
1866 
1867 	/* For simplicity, we always schema-qualify the name */
1868 	nsp_name = get_namespace_name(coll_rec->collnamespace);
1869 	coll_name = pstrdup(NameStr(coll_rec->collname));
1870 	result = list_make2(makeString(nsp_name), makeString(coll_name));
1871 
1872 	ReleaseSysCache(ht_coll);
1873 	return result;
1874 }
1875 
1876 /*
1877  * get_opclass			- fetch qualified name of an index operator class
1878  *
1879  * If the opclass is the default for the given actual_datatype, then
1880  * the return value is NIL.
1881  */
1882 static List *
1883 get_opclass(Oid opclass, Oid actual_datatype)
1884 {
1885 	List	   *result = NIL;
1886 	HeapTuple	ht_opc;
1887 	Form_pg_opclass opc_rec;
1888 
1889 	ht_opc = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
1890 	if (!HeapTupleIsValid(ht_opc))
1891 		elog(ERROR, "cache lookup failed for opclass %u", opclass);
1892 	opc_rec = (Form_pg_opclass) GETSTRUCT(ht_opc);
1893 
1894 	if (GetDefaultOpClass(actual_datatype, opc_rec->opcmethod) != opclass)
1895 	{
1896 		/* For simplicity, we always schema-qualify the name */
1897 		char	   *nsp_name = get_namespace_name(opc_rec->opcnamespace);
1898 		char	   *opc_name = pstrdup(NameStr(opc_rec->opcname));
1899 
1900 		result = list_make2(makeString(nsp_name), makeString(opc_name));
1901 	}
1902 
1903 	ReleaseSysCache(ht_opc);
1904 	return result;
1905 }
1906 
1907 
1908 /*
1909  * transformIndexConstraints
1910  *		Handle UNIQUE, PRIMARY KEY, EXCLUDE constraints, which create indexes.
1911  *		We also merge in any index definitions arising from
1912  *		LIKE ... INCLUDING INDEXES.
1913  */
1914 static void
1915 transformIndexConstraints(CreateStmtContext *cxt)
1916 {
1917 	IndexStmt  *index;
1918 	List	   *indexlist = NIL;
1919 	ListCell   *lc;
1920 
1921 	/*
1922 	 * Run through the constraints that need to generate an index. For PRIMARY
1923 	 * KEY, mark each column as NOT NULL and create an index. For UNIQUE or
1924 	 * EXCLUDE, create an index as for PRIMARY KEY, but do not insist on NOT
1925 	 * NULL.
1926 	 */
1927 	foreach(lc, cxt->ixconstraints)
1928 	{
1929 		Constraint *constraint = lfirst_node(Constraint, lc);
1930 
1931 		Assert(constraint->contype == CONSTR_PRIMARY ||
1932 			   constraint->contype == CONSTR_UNIQUE ||
1933 			   constraint->contype == CONSTR_EXCLUSION);
1934 
1935 		index = transformIndexConstraint(constraint, cxt);
1936 
1937 		indexlist = lappend(indexlist, index);
1938 	}
1939 
1940 	/*
1941 	 * Scan the index list and remove any redundant index specifications. This
1942 	 * can happen if, for instance, the user writes UNIQUE PRIMARY KEY. A
1943 	 * strict reading of SQL would suggest raising an error instead, but that
1944 	 * strikes me as too anal-retentive. - tgl 2001-02-14
1945 	 *
1946 	 * XXX in ALTER TABLE case, it'd be nice to look for duplicate
1947 	 * pre-existing indexes, too.
1948 	 */
1949 	Assert(cxt->alist == NIL);
1950 	if (cxt->pkey != NULL)
1951 	{
1952 		/* Make sure we keep the PKEY index in preference to others... */
1953 		cxt->alist = list_make1(cxt->pkey);
1954 	}
1955 
1956 	foreach(lc, indexlist)
1957 	{
1958 		bool		keep = true;
1959 		ListCell   *k;
1960 
1961 		index = lfirst(lc);
1962 
1963 		/* if it's pkey, it's already in cxt->alist */
1964 		if (index == cxt->pkey)
1965 			continue;
1966 
1967 		foreach(k, cxt->alist)
1968 		{
1969 			IndexStmt  *priorindex = lfirst(k);
1970 
1971 			if (equal(index->indexParams, priorindex->indexParams) &&
1972 				equal(index->indexIncludingParams, priorindex->indexIncludingParams) &&
1973 				equal(index->whereClause, priorindex->whereClause) &&
1974 				equal(index->excludeOpNames, priorindex->excludeOpNames) &&
1975 				strcmp(index->accessMethod, priorindex->accessMethod) == 0 &&
1976 				index->deferrable == priorindex->deferrable &&
1977 				index->initdeferred == priorindex->initdeferred)
1978 			{
1979 				priorindex->unique |= index->unique;
1980 
1981 				/*
1982 				 * If the prior index is as yet unnamed, and this one is
1983 				 * named, then transfer the name to the prior index. This
1984 				 * ensures that if we have named and unnamed constraints,
1985 				 * we'll use (at least one of) the names for the index.
1986 				 */
1987 				if (priorindex->idxname == NULL)
1988 					priorindex->idxname = index->idxname;
1989 				keep = false;
1990 				break;
1991 			}
1992 		}
1993 
1994 		if (keep)
1995 			cxt->alist = lappend(cxt->alist, index);
1996 	}
1997 }
1998 
1999 /*
2000  * transformIndexConstraint
2001  *		Transform one UNIQUE, PRIMARY KEY, or EXCLUDE constraint for
2002  *		transformIndexConstraints.
2003  */
2004 static IndexStmt *
2005 transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
2006 {
2007 	IndexStmt  *index;
2008 	ListCell   *lc;
2009 
2010 	index = makeNode(IndexStmt);
2011 
2012 	index->unique = (constraint->contype != CONSTR_EXCLUSION);
2013 	index->primary = (constraint->contype == CONSTR_PRIMARY);
2014 	if (index->primary)
2015 	{
2016 		if (cxt->pkey != NULL)
2017 			ereport(ERROR,
2018 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
2019 					 errmsg("multiple primary keys for table \"%s\" are not allowed",
2020 							cxt->relation->relname),
2021 					 parser_errposition(cxt->pstate, constraint->location)));
2022 		cxt->pkey = index;
2023 
2024 		/*
2025 		 * In ALTER TABLE case, a primary index might already exist, but
2026 		 * DefineIndex will check for it.
2027 		 */
2028 	}
2029 	index->isconstraint = true;
2030 	index->deferrable = constraint->deferrable;
2031 	index->initdeferred = constraint->initdeferred;
2032 
2033 	if (constraint->conname != NULL)
2034 		index->idxname = pstrdup(constraint->conname);
2035 	else
2036 		index->idxname = NULL;	/* DefineIndex will choose name */
2037 
2038 	index->relation = cxt->relation;
2039 	index->accessMethod = constraint->access_method ? constraint->access_method : DEFAULT_INDEX_TYPE;
2040 	index->options = constraint->options;
2041 	index->tableSpace = constraint->indexspace;
2042 	index->whereClause = constraint->where_clause;
2043 	index->indexParams = NIL;
2044 	index->indexIncludingParams = NIL;
2045 	index->excludeOpNames = NIL;
2046 	index->idxcomment = NULL;
2047 	index->indexOid = InvalidOid;
2048 	index->oldNode = InvalidOid;
2049 	index->transformed = false;
2050 	index->concurrent = false;
2051 	index->if_not_exists = false;
2052 
2053 	/*
2054 	 * If it's ALTER TABLE ADD CONSTRAINT USING INDEX, look up the index and
2055 	 * verify it's usable, then extract the implied column name list.  (We
2056 	 * will not actually need the column name list at runtime, but we need it
2057 	 * now to check for duplicate column entries below.)
2058 	 */
2059 	if (constraint->indexname != NULL)
2060 	{
2061 		char	   *index_name = constraint->indexname;
2062 		Relation	heap_rel = cxt->rel;
2063 		Oid			index_oid;
2064 		Relation	index_rel;
2065 		Form_pg_index index_form;
2066 		oidvector  *indclass;
2067 		Datum		indclassDatum;
2068 		bool		isnull;
2069 		int			i;
2070 
2071 		/* Grammar should not allow this with explicit column list */
2072 		Assert(constraint->keys == NIL);
2073 
2074 		/* Grammar should only allow PRIMARY and UNIQUE constraints */
2075 		Assert(constraint->contype == CONSTR_PRIMARY ||
2076 			   constraint->contype == CONSTR_UNIQUE);
2077 
2078 		/* Must be ALTER, not CREATE, but grammar doesn't enforce that */
2079 		if (!cxt->isalter)
2080 			ereport(ERROR,
2081 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2082 					 errmsg("cannot use an existing index in CREATE TABLE"),
2083 					 parser_errposition(cxt->pstate, constraint->location)));
2084 
2085 		/* Look for the index in the same schema as the table */
2086 		index_oid = get_relname_relid(index_name, RelationGetNamespace(heap_rel));
2087 
2088 		if (!OidIsValid(index_oid))
2089 			ereport(ERROR,
2090 					(errcode(ERRCODE_UNDEFINED_OBJECT),
2091 					 errmsg("index \"%s\" does not exist", index_name),
2092 					 parser_errposition(cxt->pstate, constraint->location)));
2093 
2094 		/* Open the index (this will throw an error if it is not an index) */
2095 		index_rel = index_open(index_oid, AccessShareLock);
2096 		index_form = index_rel->rd_index;
2097 
2098 		/* Check that it does not have an associated constraint already */
2099 		if (OidIsValid(get_index_constraint(index_oid)))
2100 			ereport(ERROR,
2101 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2102 					 errmsg("index \"%s\" is already associated with a constraint",
2103 							index_name),
2104 					 parser_errposition(cxt->pstate, constraint->location)));
2105 
2106 		/* Perform validity checks on the index */
2107 		if (index_form->indrelid != RelationGetRelid(heap_rel))
2108 			ereport(ERROR,
2109 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2110 					 errmsg("index \"%s\" does not belong to table \"%s\"",
2111 							index_name, RelationGetRelationName(heap_rel)),
2112 					 parser_errposition(cxt->pstate, constraint->location)));
2113 
2114 		if (!IndexIsValid(index_form))
2115 			ereport(ERROR,
2116 					(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2117 					 errmsg("index \"%s\" is not valid", index_name),
2118 					 parser_errposition(cxt->pstate, constraint->location)));
2119 
2120 		if (!index_form->indisunique)
2121 			ereport(ERROR,
2122 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2123 					 errmsg("\"%s\" is not a unique index", index_name),
2124 					 errdetail("Cannot create a primary key or unique constraint using such an index."),
2125 					 parser_errposition(cxt->pstate, constraint->location)));
2126 
2127 		if (RelationGetIndexExpressions(index_rel) != NIL)
2128 			ereport(ERROR,
2129 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2130 					 errmsg("index \"%s\" contains expressions", index_name),
2131 					 errdetail("Cannot create a primary key or unique constraint using such an index."),
2132 					 parser_errposition(cxt->pstate, constraint->location)));
2133 
2134 		if (RelationGetIndexPredicate(index_rel) != NIL)
2135 			ereport(ERROR,
2136 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2137 					 errmsg("\"%s\" is a partial index", index_name),
2138 					 errdetail("Cannot create a primary key or unique constraint using such an index."),
2139 					 parser_errposition(cxt->pstate, constraint->location)));
2140 
2141 		/*
2142 		 * It's probably unsafe to change a deferred index to non-deferred. (A
2143 		 * non-constraint index couldn't be deferred anyway, so this case
2144 		 * should never occur; no need to sweat, but let's check it.)
2145 		 */
2146 		if (!index_form->indimmediate && !constraint->deferrable)
2147 			ereport(ERROR,
2148 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2149 					 errmsg("\"%s\" is a deferrable index", index_name),
2150 					 errdetail("Cannot create a non-deferrable constraint using a deferrable index."),
2151 					 parser_errposition(cxt->pstate, constraint->location)));
2152 
2153 		/*
2154 		 * Insist on it being a btree.  That's the only kind that supports
2155 		 * uniqueness at the moment anyway; but we must have an index that
2156 		 * exactly matches what you'd get from plain ADD CONSTRAINT syntax,
2157 		 * else dump and reload will produce a different index (breaking
2158 		 * pg_upgrade in particular).
2159 		 */
2160 		if (index_rel->rd_rel->relam != get_index_am_oid(DEFAULT_INDEX_TYPE, false))
2161 			ereport(ERROR,
2162 					(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2163 					 errmsg("index \"%s\" is not a btree", index_name),
2164 					 parser_errposition(cxt->pstate, constraint->location)));
2165 
2166 		/* Must get indclass the hard way */
2167 		indclassDatum = SysCacheGetAttr(INDEXRELID, index_rel->rd_indextuple,
2168 										Anum_pg_index_indclass, &isnull);
2169 		Assert(!isnull);
2170 		indclass = (oidvector *) DatumGetPointer(indclassDatum);
2171 
2172 		for (i = 0; i < index_form->indnatts; i++)
2173 		{
2174 			int16		attnum = index_form->indkey.values[i];
2175 			Form_pg_attribute attform;
2176 			char	   *attname;
2177 			Oid			defopclass;
2178 
2179 			/*
2180 			 * We shouldn't see attnum == 0 here, since we already rejected
2181 			 * expression indexes.  If we do, SystemAttributeDefinition will
2182 			 * throw an error.
2183 			 */
2184 			if (attnum > 0)
2185 			{
2186 				Assert(attnum <= heap_rel->rd_att->natts);
2187 				attform = TupleDescAttr(heap_rel->rd_att, attnum - 1);
2188 			}
2189 			else
2190 				attform = SystemAttributeDefinition(attnum,
2191 													heap_rel->rd_rel->relhasoids);
2192 			attname = pstrdup(NameStr(attform->attname));
2193 
2194 			if (i < index_form->indnkeyatts)
2195 			{
2196 				/*
2197 				 * Insist on default opclass and sort options.  While the
2198 				 * index would still work as a constraint with non-default
2199 				 * settings, it might not provide exactly the same uniqueness
2200 				 * semantics as you'd get from a normally-created constraint;
2201 				 * and there's also the dump/reload problem mentioned above.
2202 				 */
2203 				defopclass = GetDefaultOpClass(attform->atttypid,
2204 											   index_rel->rd_rel->relam);
2205 				if (indclass->values[i] != defopclass ||
2206 					index_rel->rd_indoption[i] != 0)
2207 					ereport(ERROR,
2208 							(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2209 							 errmsg("index \"%s\" does not have default sorting behavior", index_name),
2210 							 errdetail("Cannot create a primary key or unique constraint using such an index."),
2211 							 parser_errposition(cxt->pstate, constraint->location)));
2212 
2213 				constraint->keys = lappend(constraint->keys, makeString(attname));
2214 			}
2215 			else
2216 				constraint->including = lappend(constraint->including, makeString(attname));
2217 		}
2218 
2219 		/* Close the index relation but keep the lock */
2220 		relation_close(index_rel, NoLock);
2221 
2222 		index->indexOid = index_oid;
2223 	}
2224 
2225 	/*
2226 	 * If it's an EXCLUDE constraint, the grammar returns a list of pairs of
2227 	 * IndexElems and operator names.  We have to break that apart into
2228 	 * separate lists.
2229 	 */
2230 	if (constraint->contype == CONSTR_EXCLUSION)
2231 	{
2232 		foreach(lc, constraint->exclusions)
2233 		{
2234 			List	   *pair = (List *) lfirst(lc);
2235 			IndexElem  *elem;
2236 			List	   *opname;
2237 
2238 			Assert(list_length(pair) == 2);
2239 			elem = linitial_node(IndexElem, pair);
2240 			opname = lsecond_node(List, pair);
2241 
2242 			index->indexParams = lappend(index->indexParams, elem);
2243 			index->excludeOpNames = lappend(index->excludeOpNames, opname);
2244 		}
2245 	}
2246 
2247 	/*
2248 	 * For UNIQUE and PRIMARY KEY, we just have a list of column names.
2249 	 *
2250 	 * Make sure referenced keys exist.  If we are making a PRIMARY KEY index,
2251 	 * also make sure they are NOT NULL, if possible. (Although we could leave
2252 	 * it to DefineIndex to mark the columns NOT NULL, it's more efficient to
2253 	 * get it right the first time.)
2254 	 */
2255 	else
2256 	{
2257 		foreach(lc, constraint->keys)
2258 		{
2259 			char	   *key = strVal(lfirst(lc));
2260 			bool		found = false;
2261 			ColumnDef  *column = NULL;
2262 			ListCell   *columns;
2263 			IndexElem  *iparam;
2264 
2265 			/* Make sure referenced column exist. */
2266 			foreach(columns, cxt->columns)
2267 			{
2268 				column = castNode(ColumnDef, lfirst(columns));
2269 				if (strcmp(column->colname, key) == 0)
2270 				{
2271 					found = true;
2272 					break;
2273 				}
2274 			}
2275 			if (found)
2276 			{
2277 				/* found column in the new table; force it to be NOT NULL */
2278 				if (constraint->contype == CONSTR_PRIMARY)
2279 					column->is_not_null = true;
2280 			}
2281 			else if (SystemAttributeByName(key, cxt->hasoids) != NULL)
2282 			{
2283 				/*
2284 				 * column will be a system column in the new table, so accept
2285 				 * it. System columns can't ever be null, so no need to worry
2286 				 * about PRIMARY/NOT NULL constraint.
2287 				 */
2288 				found = true;
2289 			}
2290 			else if (cxt->inhRelations)
2291 			{
2292 				/* try inherited tables */
2293 				ListCell   *inher;
2294 
2295 				foreach(inher, cxt->inhRelations)
2296 				{
2297 					RangeVar   *inh = castNode(RangeVar, lfirst(inher));
2298 					Relation	rel;
2299 					int			count;
2300 
2301 					rel = heap_openrv(inh, AccessShareLock);
2302 					/* check user requested inheritance from valid relkind */
2303 					if (rel->rd_rel->relkind != RELKIND_RELATION &&
2304 						rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
2305 						rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
2306 						ereport(ERROR,
2307 								(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2308 								 errmsg("inherited relation \"%s\" is not a table or foreign table",
2309 										inh->relname)));
2310 					for (count = 0; count < rel->rd_att->natts; count++)
2311 					{
2312 						Form_pg_attribute inhattr = TupleDescAttr(rel->rd_att,
2313 																  count);
2314 						char	   *inhname = NameStr(inhattr->attname);
2315 
2316 						if (inhattr->attisdropped)
2317 							continue;
2318 						if (strcmp(key, inhname) == 0)
2319 						{
2320 							found = true;
2321 
2322 							/*
2323 							 * We currently have no easy way to force an
2324 							 * inherited column to be NOT NULL at creation, if
2325 							 * its parent wasn't so already. We leave it to
2326 							 * DefineIndex to fix things up in this case.
2327 							 */
2328 							break;
2329 						}
2330 					}
2331 					heap_close(rel, NoLock);
2332 					if (found)
2333 						break;
2334 				}
2335 			}
2336 
2337 			/*
2338 			 * In the ALTER TABLE case, don't complain about index keys not
2339 			 * created in the command; they may well exist already.
2340 			 * DefineIndex will complain about them if not, and will also take
2341 			 * care of marking them NOT NULL.
2342 			 */
2343 			if (!found && !cxt->isalter)
2344 				ereport(ERROR,
2345 						(errcode(ERRCODE_UNDEFINED_COLUMN),
2346 						 errmsg("column \"%s\" named in key does not exist", key),
2347 						 parser_errposition(cxt->pstate, constraint->location)));
2348 
2349 			/* Check for PRIMARY KEY(foo, foo) */
2350 			foreach(columns, index->indexParams)
2351 			{
2352 				iparam = (IndexElem *) lfirst(columns);
2353 				if (iparam->name && strcmp(key, iparam->name) == 0)
2354 				{
2355 					if (index->primary)
2356 						ereport(ERROR,
2357 								(errcode(ERRCODE_DUPLICATE_COLUMN),
2358 								 errmsg("column \"%s\" appears twice in primary key constraint",
2359 										key),
2360 								 parser_errposition(cxt->pstate, constraint->location)));
2361 					else
2362 						ereport(ERROR,
2363 								(errcode(ERRCODE_DUPLICATE_COLUMN),
2364 								 errmsg("column \"%s\" appears twice in unique constraint",
2365 										key),
2366 								 parser_errposition(cxt->pstate, constraint->location)));
2367 				}
2368 			}
2369 
2370 			/* OK, add it to the index definition */
2371 			iparam = makeNode(IndexElem);
2372 			iparam->name = pstrdup(key);
2373 			iparam->expr = NULL;
2374 			iparam->indexcolname = NULL;
2375 			iparam->collation = NIL;
2376 			iparam->opclass = NIL;
2377 			iparam->ordering = SORTBY_DEFAULT;
2378 			iparam->nulls_ordering = SORTBY_NULLS_DEFAULT;
2379 			index->indexParams = lappend(index->indexParams, iparam);
2380 		}
2381 	}
2382 
2383 	/* Add included columns to index definition */
2384 	foreach(lc, constraint->including)
2385 	{
2386 		char	   *key = strVal(lfirst(lc));
2387 		bool		found = false;
2388 		ColumnDef  *column = NULL;
2389 		ListCell   *columns;
2390 		IndexElem  *iparam;
2391 
2392 		foreach(columns, cxt->columns)
2393 		{
2394 			column = lfirst_node(ColumnDef, columns);
2395 			if (strcmp(column->colname, key) == 0)
2396 			{
2397 				found = true;
2398 				break;
2399 			}
2400 		}
2401 
2402 		if (!found)
2403 		{
2404 			if (SystemAttributeByName(key, cxt->hasoids) != NULL)
2405 			{
2406 				/*
2407 				 * column will be a system column in the new table, so accept
2408 				 * it. System columns can't ever be null, so no need to worry
2409 				 * about PRIMARY/NOT NULL constraint.
2410 				 */
2411 				found = true;
2412 			}
2413 			else if (cxt->inhRelations)
2414 			{
2415 				/* try inherited tables */
2416 				ListCell   *inher;
2417 
2418 				foreach(inher, cxt->inhRelations)
2419 				{
2420 					RangeVar   *inh = lfirst_node(RangeVar, inher);
2421 					Relation	rel;
2422 					int			count;
2423 
2424 					rel = heap_openrv(inh, AccessShareLock);
2425 					/* check user requested inheritance from valid relkind */
2426 					if (rel->rd_rel->relkind != RELKIND_RELATION &&
2427 						rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
2428 						rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
2429 						ereport(ERROR,
2430 								(errcode(ERRCODE_WRONG_OBJECT_TYPE),
2431 								 errmsg("inherited relation \"%s\" is not a table or foreign table",
2432 										inh->relname)));
2433 					for (count = 0; count < rel->rd_att->natts; count++)
2434 					{
2435 						Form_pg_attribute inhattr = TupleDescAttr(rel->rd_att,
2436 																  count);
2437 						char	   *inhname = NameStr(inhattr->attname);
2438 
2439 						if (inhattr->attisdropped)
2440 							continue;
2441 						if (strcmp(key, inhname) == 0)
2442 						{
2443 							found = true;
2444 
2445 							/*
2446 							 * We currently have no easy way to force an
2447 							 * inherited column to be NOT NULL at creation, if
2448 							 * its parent wasn't so already. We leave it to
2449 							 * DefineIndex to fix things up in this case.
2450 							 */
2451 							break;
2452 						}
2453 					}
2454 					heap_close(rel, NoLock);
2455 					if (found)
2456 						break;
2457 				}
2458 			}
2459 		}
2460 
2461 		/*
2462 		 * In the ALTER TABLE case, don't complain about index keys not
2463 		 * created in the command; they may well exist already. DefineIndex
2464 		 * will complain about them if not, and will also take care of marking
2465 		 * them NOT NULL.
2466 		 */
2467 		if (!found && !cxt->isalter)
2468 			ereport(ERROR,
2469 					(errcode(ERRCODE_UNDEFINED_COLUMN),
2470 					 errmsg("column \"%s\" named in key does not exist", key),
2471 					 parser_errposition(cxt->pstate, constraint->location)));
2472 
2473 		/* OK, add it to the index definition */
2474 		iparam = makeNode(IndexElem);
2475 		iparam->name = pstrdup(key);
2476 		iparam->expr = NULL;
2477 		iparam->indexcolname = NULL;
2478 		iparam->collation = NIL;
2479 		iparam->opclass = NIL;
2480 		index->indexIncludingParams = lappend(index->indexIncludingParams, iparam);
2481 	}
2482 
2483 	return index;
2484 }
2485 
2486 /*
2487  * transformExtendedStatistics
2488  *     Handle extended statistic objects
2489  *
2490  * Right now, there's nothing to do here, so we just append the list to
2491  * the existing "after" list.
2492  */
2493 static void
2494 transformExtendedStatistics(CreateStmtContext *cxt)
2495 {
2496 	cxt->alist = list_concat(cxt->alist, cxt->extstats);
2497 }
2498 
2499 /*
2500  * transformCheckConstraints
2501  *		handle CHECK constraints
2502  *
2503  * Right now, there's nothing to do here when called from ALTER TABLE,
2504  * but the other constraint-transformation functions are called in both
2505  * the CREATE TABLE and ALTER TABLE paths, so do the same here, and just
2506  * don't do anything if we're not authorized to skip validation.
2507  */
2508 static void
2509 transformCheckConstraints(CreateStmtContext *cxt, bool skipValidation)
2510 {
2511 	ListCell   *ckclist;
2512 
2513 	if (cxt->ckconstraints == NIL)
2514 		return;
2515 
2516 	/*
2517 	 * If creating a new table (but not a foreign table), we can safely skip
2518 	 * validation of check constraints, and nonetheless mark them valid. (This
2519 	 * will override any user-supplied NOT VALID flag.)
2520 	 */
2521 	if (skipValidation)
2522 	{
2523 		foreach(ckclist, cxt->ckconstraints)
2524 		{
2525 			Constraint *constraint = (Constraint *) lfirst(ckclist);
2526 
2527 			constraint->skip_validation = true;
2528 			constraint->initially_valid = true;
2529 		}
2530 	}
2531 }
2532 
2533 /*
2534  * transformFKConstraints
2535  *		handle FOREIGN KEY constraints
2536  */
2537 static void
2538 transformFKConstraints(CreateStmtContext *cxt,
2539 					   bool skipValidation, bool isAddConstraint)
2540 {
2541 	ListCell   *fkclist;
2542 
2543 	if (cxt->fkconstraints == NIL)
2544 		return;
2545 
2546 	/*
2547 	 * If CREATE TABLE or adding a column with NULL default, we can safely
2548 	 * skip validation of FK constraints, and nonetheless mark them valid.
2549 	 * (This will override any user-supplied NOT VALID flag.)
2550 	 */
2551 	if (skipValidation)
2552 	{
2553 		foreach(fkclist, cxt->fkconstraints)
2554 		{
2555 			Constraint *constraint = (Constraint *) lfirst(fkclist);
2556 
2557 			constraint->skip_validation = true;
2558 			constraint->initially_valid = true;
2559 		}
2560 	}
2561 
2562 	/*
2563 	 * For CREATE TABLE or ALTER TABLE ADD COLUMN, gin up an ALTER TABLE ADD
2564 	 * CONSTRAINT command to execute after the basic command is complete. (If
2565 	 * called from ADD CONSTRAINT, that routine will add the FK constraints to
2566 	 * its own subcommand list.)
2567 	 *
2568 	 * Note: the ADD CONSTRAINT command must also execute after any index
2569 	 * creation commands.  Thus, this should run after
2570 	 * transformIndexConstraints, so that the CREATE INDEX commands are
2571 	 * already in cxt->alist.  See also the handling of cxt->likeclauses.
2572 	 */
2573 	if (!isAddConstraint)
2574 	{
2575 		AlterTableStmt *alterstmt = makeNode(AlterTableStmt);
2576 
2577 		alterstmt->relation = cxt->relation;
2578 		alterstmt->cmds = NIL;
2579 		alterstmt->relkind = OBJECT_TABLE;
2580 
2581 		foreach(fkclist, cxt->fkconstraints)
2582 		{
2583 			Constraint *constraint = (Constraint *) lfirst(fkclist);
2584 			AlterTableCmd *altercmd = makeNode(AlterTableCmd);
2585 
2586 			altercmd->subtype = AT_ProcessedConstraint;
2587 			altercmd->name = NULL;
2588 			altercmd->def = (Node *) constraint;
2589 			alterstmt->cmds = lappend(alterstmt->cmds, altercmd);
2590 		}
2591 
2592 		cxt->alist = lappend(cxt->alist, alterstmt);
2593 	}
2594 }
2595 
2596 /*
2597  * transformIndexStmt - parse analysis for CREATE INDEX and ALTER TABLE
2598  *
2599  * Note: this is a no-op for an index not using either index expressions or
2600  * a predicate expression.  There are several code paths that create indexes
2601  * without bothering to call this, because they know they don't have any
2602  * such expressions to deal with.
2603  *
2604  * To avoid race conditions, it's important that this function rely only on
2605  * the passed-in relid (and not on stmt->relation) to determine the target
2606  * relation.
2607  */
2608 IndexStmt *
2609 transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString)
2610 {
2611 	ParseState *pstate;
2612 	RangeTblEntry *rte;
2613 	ListCell   *l;
2614 	Relation	rel;
2615 
2616 	/* Nothing to do if statement already transformed. */
2617 	if (stmt->transformed)
2618 		return stmt;
2619 
2620 	/*
2621 	 * We must not scribble on the passed-in IndexStmt, so copy it.  (This is
2622 	 * overkill, but easy.)
2623 	 */
2624 	stmt = copyObject(stmt);
2625 
2626 	/* Set up pstate */
2627 	pstate = make_parsestate(NULL);
2628 	pstate->p_sourcetext = queryString;
2629 
2630 	/*
2631 	 * Put the parent table into the rtable so that the expressions can refer
2632 	 * to its fields without qualification.  Caller is responsible for locking
2633 	 * relation, but we still need to open it.
2634 	 */
2635 	rel = relation_open(relid, NoLock);
2636 	rte = addRangeTableEntryForRelation(pstate, rel, NULL, false, true);
2637 
2638 	/* no to join list, yes to namespaces */
2639 	addRTEtoQuery(pstate, rte, false, true, true);
2640 
2641 	/* take care of the where clause */
2642 	if (stmt->whereClause)
2643 	{
2644 		stmt->whereClause = transformWhereClause(pstate,
2645 												 stmt->whereClause,
2646 												 EXPR_KIND_INDEX_PREDICATE,
2647 												 "WHERE");
2648 		/* we have to fix its collations too */
2649 		assign_expr_collations(pstate, stmt->whereClause);
2650 	}
2651 
2652 	/* take care of any index expressions */
2653 	foreach(l, stmt->indexParams)
2654 	{
2655 		IndexElem  *ielem = (IndexElem *) lfirst(l);
2656 
2657 		if (ielem->expr)
2658 		{
2659 			/* Extract preliminary index col name before transforming expr */
2660 			if (ielem->indexcolname == NULL)
2661 				ielem->indexcolname = FigureIndexColname(ielem->expr);
2662 
2663 			/* Now do parse transformation of the expression */
2664 			ielem->expr = transformExpr(pstate, ielem->expr,
2665 										EXPR_KIND_INDEX_EXPRESSION);
2666 
2667 			/* We have to fix its collations too */
2668 			assign_expr_collations(pstate, ielem->expr);
2669 
2670 			/*
2671 			 * transformExpr() should have already rejected subqueries,
2672 			 * aggregates, window functions, and SRFs, based on the EXPR_KIND_
2673 			 * for an index expression.
2674 			 *
2675 			 * DefineIndex() will make more checks.
2676 			 */
2677 		}
2678 	}
2679 
2680 	/*
2681 	 * Check that only the base rel is mentioned.  (This should be dead code
2682 	 * now that add_missing_from is history.)
2683 	 */
2684 	if (list_length(pstate->p_rtable) != 1)
2685 		ereport(ERROR,
2686 				(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
2687 				 errmsg("index expressions and predicates can refer only to the table being indexed")));
2688 
2689 	free_parsestate(pstate);
2690 
2691 	/* Close relation */
2692 	heap_close(rel, NoLock);
2693 
2694 	/* Mark statement as successfully transformed */
2695 	stmt->transformed = true;
2696 
2697 	return stmt;
2698 }
2699 
2700 
2701 /*
2702  * transformRuleStmt -
2703  *	  transform a CREATE RULE Statement. The action is a list of parse
2704  *	  trees which is transformed into a list of query trees, and we also
2705  *	  transform the WHERE clause if any.
2706  *
2707  * actions and whereClause are output parameters that receive the
2708  * transformed results.
2709  *
2710  * Note that we must not scribble on the passed-in RuleStmt, so we do
2711  * copyObject() on the actions and WHERE clause.
2712  */
2713 void
2714 transformRuleStmt(RuleStmt *stmt, const char *queryString,
2715 				  List **actions, Node **whereClause)
2716 {
2717 	Relation	rel;
2718 	ParseState *pstate;
2719 	RangeTblEntry *oldrte;
2720 	RangeTblEntry *newrte;
2721 
2722 	/*
2723 	 * To avoid deadlock, make sure the first thing we do is grab
2724 	 * AccessExclusiveLock on the target relation.  This will be needed by
2725 	 * DefineQueryRewrite(), and we don't want to grab a lesser lock
2726 	 * beforehand.
2727 	 */
2728 	rel = heap_openrv(stmt->relation, AccessExclusiveLock);
2729 
2730 	if (rel->rd_rel->relkind == RELKIND_MATVIEW)
2731 		ereport(ERROR,
2732 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2733 				 errmsg("rules on materialized views are not supported")));
2734 
2735 	/* Set up pstate */
2736 	pstate = make_parsestate(NULL);
2737 	pstate->p_sourcetext = queryString;
2738 
2739 	/*
2740 	 * NOTE: 'OLD' must always have a varno equal to 1 and 'NEW' equal to 2.
2741 	 * Set up their RTEs in the main pstate for use in parsing the rule
2742 	 * qualification.
2743 	 */
2744 	oldrte = addRangeTableEntryForRelation(pstate, rel,
2745 										   makeAlias("old", NIL),
2746 										   false, false);
2747 	newrte = addRangeTableEntryForRelation(pstate, rel,
2748 										   makeAlias("new", NIL),
2749 										   false, false);
2750 	/* Must override addRangeTableEntry's default access-check flags */
2751 	oldrte->requiredPerms = 0;
2752 	newrte->requiredPerms = 0;
2753 
2754 	/*
2755 	 * They must be in the namespace too for lookup purposes, but only add the
2756 	 * one(s) that are relevant for the current kind of rule.  In an UPDATE
2757 	 * rule, quals must refer to OLD.field or NEW.field to be unambiguous, but
2758 	 * there's no need to be so picky for INSERT & DELETE.  We do not add them
2759 	 * to the joinlist.
2760 	 */
2761 	switch (stmt->event)
2762 	{
2763 		case CMD_SELECT:
2764 			addRTEtoQuery(pstate, oldrte, false, true, true);
2765 			break;
2766 		case CMD_UPDATE:
2767 			addRTEtoQuery(pstate, oldrte, false, true, true);
2768 			addRTEtoQuery(pstate, newrte, false, true, true);
2769 			break;
2770 		case CMD_INSERT:
2771 			addRTEtoQuery(pstate, newrte, false, true, true);
2772 			break;
2773 		case CMD_DELETE:
2774 			addRTEtoQuery(pstate, oldrte, false, true, true);
2775 			break;
2776 		default:
2777 			elog(ERROR, "unrecognized event type: %d",
2778 				 (int) stmt->event);
2779 			break;
2780 	}
2781 
2782 	/* take care of the where clause */
2783 	*whereClause = transformWhereClause(pstate,
2784 										(Node *) copyObject(stmt->whereClause),
2785 										EXPR_KIND_WHERE,
2786 										"WHERE");
2787 	/* we have to fix its collations too */
2788 	assign_expr_collations(pstate, *whereClause);
2789 
2790 	/* this is probably dead code without add_missing_from: */
2791 	if (list_length(pstate->p_rtable) != 2) /* naughty, naughty... */
2792 		ereport(ERROR,
2793 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2794 				 errmsg("rule WHERE condition cannot contain references to other relations")));
2795 
2796 	/*
2797 	 * 'instead nothing' rules with a qualification need a query rangetable so
2798 	 * the rewrite handler can add the negated rule qualification to the
2799 	 * original query. We create a query with the new command type CMD_NOTHING
2800 	 * here that is treated specially by the rewrite system.
2801 	 */
2802 	if (stmt->actions == NIL)
2803 	{
2804 		Query	   *nothing_qry = makeNode(Query);
2805 
2806 		nothing_qry->commandType = CMD_NOTHING;
2807 		nothing_qry->rtable = pstate->p_rtable;
2808 		nothing_qry->jointree = makeFromExpr(NIL, NULL);	/* no join wanted */
2809 
2810 		*actions = list_make1(nothing_qry);
2811 	}
2812 	else
2813 	{
2814 		ListCell   *l;
2815 		List	   *newactions = NIL;
2816 
2817 		/*
2818 		 * transform each statement, like parse_sub_analyze()
2819 		 */
2820 		foreach(l, stmt->actions)
2821 		{
2822 			Node	   *action = (Node *) lfirst(l);
2823 			ParseState *sub_pstate = make_parsestate(NULL);
2824 			Query	   *sub_qry,
2825 					   *top_subqry;
2826 			bool		has_old,
2827 						has_new;
2828 
2829 			/*
2830 			 * Since outer ParseState isn't parent of inner, have to pass down
2831 			 * the query text by hand.
2832 			 */
2833 			sub_pstate->p_sourcetext = queryString;
2834 
2835 			/*
2836 			 * Set up OLD/NEW in the rtable for this statement.  The entries
2837 			 * are added only to relnamespace, not varnamespace, because we
2838 			 * don't want them to be referred to by unqualified field names
2839 			 * nor "*" in the rule actions.  We decide later whether to put
2840 			 * them in the joinlist.
2841 			 */
2842 			oldrte = addRangeTableEntryForRelation(sub_pstate, rel,
2843 												   makeAlias("old", NIL),
2844 												   false, false);
2845 			newrte = addRangeTableEntryForRelation(sub_pstate, rel,
2846 												   makeAlias("new", NIL),
2847 												   false, false);
2848 			oldrte->requiredPerms = 0;
2849 			newrte->requiredPerms = 0;
2850 			addRTEtoQuery(sub_pstate, oldrte, false, true, false);
2851 			addRTEtoQuery(sub_pstate, newrte, false, true, false);
2852 
2853 			/* Transform the rule action statement */
2854 			top_subqry = transformStmt(sub_pstate,
2855 									   (Node *) copyObject(action));
2856 
2857 			/*
2858 			 * We cannot support utility-statement actions (eg NOTIFY) with
2859 			 * nonempty rule WHERE conditions, because there's no way to make
2860 			 * the utility action execute conditionally.
2861 			 */
2862 			if (top_subqry->commandType == CMD_UTILITY &&
2863 				*whereClause != NULL)
2864 				ereport(ERROR,
2865 						(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2866 						 errmsg("rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions")));
2867 
2868 			/*
2869 			 * If the action is INSERT...SELECT, OLD/NEW have been pushed down
2870 			 * into the SELECT, and that's what we need to look at. (Ugly
2871 			 * kluge ... try to fix this when we redesign querytrees.)
2872 			 */
2873 			sub_qry = getInsertSelectQuery(top_subqry, NULL);
2874 
2875 			/*
2876 			 * If the sub_qry is a setop, we cannot attach any qualifications
2877 			 * to it, because the planner won't notice them.  This could
2878 			 * perhaps be relaxed someday, but for now, we may as well reject
2879 			 * such a rule immediately.
2880 			 */
2881 			if (sub_qry->setOperations != NULL && *whereClause != NULL)
2882 				ereport(ERROR,
2883 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2884 						 errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
2885 
2886 			/*
2887 			 * Validate action's use of OLD/NEW, qual too
2888 			 */
2889 			has_old =
2890 				rangeTableEntry_used((Node *) sub_qry, PRS2_OLD_VARNO, 0) ||
2891 				rangeTableEntry_used(*whereClause, PRS2_OLD_VARNO, 0);
2892 			has_new =
2893 				rangeTableEntry_used((Node *) sub_qry, PRS2_NEW_VARNO, 0) ||
2894 				rangeTableEntry_used(*whereClause, PRS2_NEW_VARNO, 0);
2895 
2896 			switch (stmt->event)
2897 			{
2898 				case CMD_SELECT:
2899 					if (has_old)
2900 						ereport(ERROR,
2901 								(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2902 								 errmsg("ON SELECT rule cannot use OLD")));
2903 					if (has_new)
2904 						ereport(ERROR,
2905 								(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2906 								 errmsg("ON SELECT rule cannot use NEW")));
2907 					break;
2908 				case CMD_UPDATE:
2909 					/* both are OK */
2910 					break;
2911 				case CMD_INSERT:
2912 					if (has_old)
2913 						ereport(ERROR,
2914 								(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2915 								 errmsg("ON INSERT rule cannot use OLD")));
2916 					break;
2917 				case CMD_DELETE:
2918 					if (has_new)
2919 						ereport(ERROR,
2920 								(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
2921 								 errmsg("ON DELETE rule cannot use NEW")));
2922 					break;
2923 				default:
2924 					elog(ERROR, "unrecognized event type: %d",
2925 						 (int) stmt->event);
2926 					break;
2927 			}
2928 
2929 			/*
2930 			 * OLD/NEW are not allowed in WITH queries, because they would
2931 			 * amount to outer references for the WITH, which we disallow.
2932 			 * However, they were already in the outer rangetable when we
2933 			 * analyzed the query, so we have to check.
2934 			 *
2935 			 * Note that in the INSERT...SELECT case, we need to examine the
2936 			 * CTE lists of both top_subqry and sub_qry.
2937 			 *
2938 			 * Note that we aren't digging into the body of the query looking
2939 			 * for WITHs in nested sub-SELECTs.  A WITH down there can
2940 			 * legitimately refer to OLD/NEW, because it'd be an
2941 			 * indirect-correlated outer reference.
2942 			 */
2943 			if (rangeTableEntry_used((Node *) top_subqry->cteList,
2944 									 PRS2_OLD_VARNO, 0) ||
2945 				rangeTableEntry_used((Node *) sub_qry->cteList,
2946 									 PRS2_OLD_VARNO, 0))
2947 				ereport(ERROR,
2948 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2949 						 errmsg("cannot refer to OLD within WITH query")));
2950 			if (rangeTableEntry_used((Node *) top_subqry->cteList,
2951 									 PRS2_NEW_VARNO, 0) ||
2952 				rangeTableEntry_used((Node *) sub_qry->cteList,
2953 									 PRS2_NEW_VARNO, 0))
2954 				ereport(ERROR,
2955 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2956 						 errmsg("cannot refer to NEW within WITH query")));
2957 
2958 			/*
2959 			 * For efficiency's sake, add OLD to the rule action's jointree
2960 			 * only if it was actually referenced in the statement or qual.
2961 			 *
2962 			 * For INSERT, NEW is not really a relation (only a reference to
2963 			 * the to-be-inserted tuple) and should never be added to the
2964 			 * jointree.
2965 			 *
2966 			 * For UPDATE, we treat NEW as being another kind of reference to
2967 			 * OLD, because it represents references to *transformed* tuples
2968 			 * of the existing relation.  It would be wrong to enter NEW
2969 			 * separately in the jointree, since that would cause a double
2970 			 * join of the updated relation.  It's also wrong to fail to make
2971 			 * a jointree entry if only NEW and not OLD is mentioned.
2972 			 */
2973 			if (has_old || (has_new && stmt->event == CMD_UPDATE))
2974 			{
2975 				/*
2976 				 * If sub_qry is a setop, manipulating its jointree will do no
2977 				 * good at all, because the jointree is dummy. (This should be
2978 				 * a can't-happen case because of prior tests.)
2979 				 */
2980 				if (sub_qry->setOperations != NULL)
2981 					ereport(ERROR,
2982 							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2983 							 errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented")));
2984 				/* hack so we can use addRTEtoQuery() */
2985 				sub_pstate->p_rtable = sub_qry->rtable;
2986 				sub_pstate->p_joinlist = sub_qry->jointree->fromlist;
2987 				addRTEtoQuery(sub_pstate, oldrte, true, false, false);
2988 				sub_qry->jointree->fromlist = sub_pstate->p_joinlist;
2989 			}
2990 
2991 			newactions = lappend(newactions, top_subqry);
2992 
2993 			free_parsestate(sub_pstate);
2994 		}
2995 
2996 		*actions = newactions;
2997 	}
2998 
2999 	free_parsestate(pstate);
3000 
3001 	/* Close relation, but keep the exclusive lock */
3002 	heap_close(rel, NoLock);
3003 }
3004 
3005 
3006 /*
3007  * transformAlterTableStmt -
3008  *		parse analysis for ALTER TABLE
3009  *
3010  * Returns a List of utility commands to be done in sequence.  One of these
3011  * will be the transformed AlterTableStmt, but there may be additional actions
3012  * to be done before and after the actual AlterTable() call.
3013  *
3014  * To avoid race conditions, it's important that this function rely only on
3015  * the passed-in relid (and not on stmt->relation) to determine the target
3016  * relation.
3017  */
3018 List *
3019 transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
3020 						const char *queryString)
3021 {
3022 	Relation	rel;
3023 	ParseState *pstate;
3024 	CreateStmtContext cxt;
3025 	List	   *result;
3026 	List	   *save_alist;
3027 	ListCell   *lcmd,
3028 			   *l;
3029 	List	   *newcmds = NIL;
3030 	bool		skipValidation = true;
3031 	AlterTableCmd *newcmd;
3032 	RangeTblEntry *rte;
3033 
3034 	/*
3035 	 * We must not scribble on the passed-in AlterTableStmt, so copy it. (This
3036 	 * is overkill, but easy.)
3037 	 */
3038 	stmt = copyObject(stmt);
3039 
3040 	/* Caller is responsible for locking the relation */
3041 	rel = relation_open(relid, NoLock);
3042 
3043 	/* Set up pstate */
3044 	pstate = make_parsestate(NULL);
3045 	pstate->p_sourcetext = queryString;
3046 	rte = addRangeTableEntryForRelation(pstate,
3047 										rel,
3048 										NULL,
3049 										false,
3050 										true);
3051 	addRTEtoQuery(pstate, rte, false, true, true);
3052 
3053 	/* Set up CreateStmtContext */
3054 	cxt.pstate = pstate;
3055 	if (stmt->relkind == OBJECT_FOREIGN_TABLE)
3056 	{
3057 		cxt.stmtType = "ALTER FOREIGN TABLE";
3058 		cxt.isforeign = true;
3059 	}
3060 	else
3061 	{
3062 		cxt.stmtType = "ALTER TABLE";
3063 		cxt.isforeign = false;
3064 	}
3065 	cxt.relation = stmt->relation;
3066 	cxt.rel = rel;
3067 	cxt.inhRelations = NIL;
3068 	cxt.isalter = true;
3069 	cxt.hasoids = false;		/* need not be right */
3070 	cxt.columns = NIL;
3071 	cxt.ckconstraints = NIL;
3072 	cxt.fkconstraints = NIL;
3073 	cxt.ixconstraints = NIL;
3074 	cxt.likeclauses = NIL;
3075 	cxt.extstats = NIL;
3076 	cxt.blist = NIL;
3077 	cxt.alist = NIL;
3078 	cxt.pkey = NULL;
3079 	cxt.ispartitioned = (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
3080 	cxt.partbound = NULL;
3081 	cxt.ofType = false;
3082 
3083 	/*
3084 	 * The only subtypes that currently require parse transformation handling
3085 	 * are ADD COLUMN, ADD CONSTRAINT and SET DATA TYPE.  These largely re-use
3086 	 * code from CREATE TABLE.
3087 	 */
3088 	foreach(lcmd, stmt->cmds)
3089 	{
3090 		AlterTableCmd *cmd = (AlterTableCmd *) lfirst(lcmd);
3091 
3092 		switch (cmd->subtype)
3093 		{
3094 			case AT_AddColumn:
3095 			case AT_AddColumnToView:
3096 				{
3097 					ColumnDef  *def = castNode(ColumnDef, cmd->def);
3098 
3099 					transformColumnDefinition(&cxt, def);
3100 
3101 					/*
3102 					 * If the column has a non-null default, we can't skip
3103 					 * validation of foreign keys.
3104 					 */
3105 					if (def->raw_default != NULL)
3106 						skipValidation = false;
3107 
3108 					/*
3109 					 * All constraints are processed in other ways. Remove the
3110 					 * original list
3111 					 */
3112 					def->constraints = NIL;
3113 
3114 					newcmds = lappend(newcmds, cmd);
3115 					break;
3116 				}
3117 
3118 			case AT_AddConstraint:
3119 
3120 				/*
3121 				 * The original AddConstraint cmd node doesn't go to newcmds
3122 				 */
3123 				if (IsA(cmd->def, Constraint))
3124 				{
3125 					transformTableConstraint(&cxt, (Constraint *) cmd->def);
3126 					if (((Constraint *) cmd->def)->contype == CONSTR_FOREIGN)
3127 						skipValidation = false;
3128 				}
3129 				else
3130 					elog(ERROR, "unrecognized node type: %d",
3131 						 (int) nodeTag(cmd->def));
3132 				break;
3133 
3134 			case AT_ProcessedConstraint:
3135 
3136 				/*
3137 				 * Already-transformed ADD CONSTRAINT, so just make it look
3138 				 * like the standard case.
3139 				 */
3140 				cmd->subtype = AT_AddConstraint;
3141 				newcmds = lappend(newcmds, cmd);
3142 				break;
3143 
3144 			case AT_AlterColumnType:
3145 				{
3146 					ColumnDef  *def = (ColumnDef *) cmd->def;
3147 					AttrNumber	attnum;
3148 
3149 					/*
3150 					 * For ALTER COLUMN TYPE, transform the USING clause if
3151 					 * one was specified.
3152 					 */
3153 					if (def->raw_default)
3154 					{
3155 						def->cooked_default =
3156 							transformExpr(pstate, def->raw_default,
3157 										  EXPR_KIND_ALTER_COL_TRANSFORM);
3158 					}
3159 
3160 					/*
3161 					 * For identity column, create ALTER SEQUENCE command to
3162 					 * change the data type of the sequence.
3163 					 */
3164 					attnum = get_attnum(relid, cmd->name);
3165 
3166 					/*
3167 					 * if attribute not found, something will error about it
3168 					 * later
3169 					 */
3170 					if (attnum != InvalidAttrNumber && get_attidentity(relid, attnum))
3171 					{
3172 						Oid			seq_relid = getOwnedSequence(relid, attnum);
3173 						Oid			typeOid = typenameTypeId(pstate, def->typeName);
3174 						AlterSeqStmt *altseqstmt = makeNode(AlterSeqStmt);
3175 
3176 						altseqstmt->sequence = makeRangeVar(get_namespace_name(get_rel_namespace(seq_relid)),
3177 															get_rel_name(seq_relid),
3178 															-1);
3179 						altseqstmt->options = list_make1(makeDefElem("as", (Node *) makeTypeNameFromOid(typeOid, -1), -1));
3180 						altseqstmt->for_identity = true;
3181 						cxt.blist = lappend(cxt.blist, altseqstmt);
3182 					}
3183 
3184 					newcmds = lappend(newcmds, cmd);
3185 					break;
3186 				}
3187 
3188 			case AT_AddIdentity:
3189 				{
3190 					Constraint *def = castNode(Constraint, cmd->def);
3191 					ColumnDef  *newdef = makeNode(ColumnDef);
3192 					AttrNumber	attnum;
3193 
3194 					newdef->colname = cmd->name;
3195 					newdef->identity = def->generated_when;
3196 					cmd->def = (Node *) newdef;
3197 
3198 					attnum = get_attnum(relid, cmd->name);
3199 
3200 					/*
3201 					 * if attribute not found, something will error about it
3202 					 * later
3203 					 */
3204 					if (attnum != InvalidAttrNumber)
3205 						generateSerialExtraStmts(&cxt, newdef,
3206 												 get_atttype(relid, attnum),
3207 												 def->options, true,
3208 												 NULL, NULL);
3209 
3210 					newcmds = lappend(newcmds, cmd);
3211 					break;
3212 				}
3213 
3214 			case AT_SetIdentity:
3215 				{
3216 					/*
3217 					 * Create an ALTER SEQUENCE statement for the internal
3218 					 * sequence of the identity column.
3219 					 */
3220 					ListCell   *lc;
3221 					List	   *newseqopts = NIL;
3222 					List	   *newdef = NIL;
3223 					List	   *seqlist;
3224 					AttrNumber	attnum;
3225 
3226 					/*
3227 					 * Split options into those handled by ALTER SEQUENCE and
3228 					 * those for ALTER TABLE proper.
3229 					 */
3230 					foreach(lc, castNode(List, cmd->def))
3231 					{
3232 						DefElem    *def = lfirst_node(DefElem, lc);
3233 
3234 						if (strcmp(def->defname, "generated") == 0)
3235 							newdef = lappend(newdef, def);
3236 						else
3237 							newseqopts = lappend(newseqopts, def);
3238 					}
3239 
3240 					attnum = get_attnum(relid, cmd->name);
3241 
3242 					if (attnum)
3243 					{
3244 						seqlist = getOwnedSequences(relid, attnum);
3245 						if (seqlist)
3246 						{
3247 							AlterSeqStmt *seqstmt;
3248 							Oid			seq_relid;
3249 
3250 							seqstmt = makeNode(AlterSeqStmt);
3251 							seq_relid = linitial_oid(seqlist);
3252 							seqstmt->sequence = makeRangeVar(get_namespace_name(get_rel_namespace(seq_relid)),
3253 															 get_rel_name(seq_relid), -1);
3254 							seqstmt->options = newseqopts;
3255 							seqstmt->for_identity = true;
3256 							seqstmt->missing_ok = false;
3257 
3258 							cxt.alist = lappend(cxt.alist, seqstmt);
3259 						}
3260 					}
3261 
3262 					/*
3263 					 * If column was not found or was not an identity column,
3264 					 * we just let the ALTER TABLE command error out later.
3265 					 */
3266 
3267 					cmd->def = (Node *) newdef;
3268 					newcmds = lappend(newcmds, cmd);
3269 					break;
3270 				}
3271 
3272 			case AT_AttachPartition:
3273 			case AT_DetachPartition:
3274 				{
3275 					PartitionCmd *partcmd = (PartitionCmd *) cmd->def;
3276 
3277 					transformPartitionCmd(&cxt, partcmd);
3278 					/* assign transformed value of the partition bound */
3279 					partcmd->bound = cxt.partbound;
3280 				}
3281 
3282 				newcmds = lappend(newcmds, cmd);
3283 				break;
3284 
3285 			default:
3286 				newcmds = lappend(newcmds, cmd);
3287 				break;
3288 		}
3289 	}
3290 
3291 	/*
3292 	 * transformIndexConstraints wants cxt.alist to contain only index
3293 	 * statements, so transfer anything we already have into save_alist
3294 	 * immediately.
3295 	 */
3296 	save_alist = cxt.alist;
3297 	cxt.alist = NIL;
3298 
3299 	/* Postprocess constraints */
3300 	transformIndexConstraints(&cxt);
3301 	transformFKConstraints(&cxt, skipValidation, true);
3302 	transformCheckConstraints(&cxt, false);
3303 
3304 	/*
3305 	 * Push any index-creation commands into the ALTER, so that they can be
3306 	 * scheduled nicely by tablecmds.c.  Note that tablecmds.c assumes that
3307 	 * the IndexStmt attached to an AT_AddIndex or AT_AddIndexConstraint
3308 	 * subcommand has already been through transformIndexStmt.
3309 	 */
3310 	foreach(l, cxt.alist)
3311 	{
3312 		IndexStmt  *idxstmt = lfirst_node(IndexStmt, l);
3313 
3314 		idxstmt = transformIndexStmt(relid, idxstmt, queryString);
3315 		newcmd = makeNode(AlterTableCmd);
3316 		newcmd->subtype = OidIsValid(idxstmt->indexOid) ? AT_AddIndexConstraint : AT_AddIndex;
3317 		newcmd->def = (Node *) idxstmt;
3318 		newcmds = lappend(newcmds, newcmd);
3319 	}
3320 	cxt.alist = NIL;
3321 
3322 	/* Append any CHECK or FK constraints to the commands list */
3323 	foreach(l, cxt.ckconstraints)
3324 	{
3325 		newcmd = makeNode(AlterTableCmd);
3326 		newcmd->subtype = AT_AddConstraint;
3327 		newcmd->def = (Node *) lfirst(l);
3328 		newcmds = lappend(newcmds, newcmd);
3329 	}
3330 	foreach(l, cxt.fkconstraints)
3331 	{
3332 		newcmd = makeNode(AlterTableCmd);
3333 		newcmd->subtype = AT_AddConstraint;
3334 		newcmd->def = (Node *) lfirst(l);
3335 		newcmds = lappend(newcmds, newcmd);
3336 	}
3337 
3338 	/* Append extended statistic objects */
3339 	transformExtendedStatistics(&cxt);
3340 
3341 	/* Close rel */
3342 	relation_close(rel, NoLock);
3343 
3344 	/*
3345 	 * Output results.
3346 	 */
3347 	stmt->cmds = newcmds;
3348 
3349 	result = lappend(cxt.blist, stmt);
3350 	result = list_concat(result, cxt.alist);
3351 	result = list_concat(result, save_alist);
3352 
3353 	return result;
3354 }
3355 
3356 
3357 /*
3358  * Preprocess a list of column constraint clauses
3359  * to attach constraint attributes to their primary constraint nodes
3360  * and detect inconsistent/misplaced constraint attributes.
3361  *
3362  * NOTE: currently, attributes are only supported for FOREIGN KEY, UNIQUE,
3363  * EXCLUSION, and PRIMARY KEY constraints, but someday they ought to be
3364  * supported for other constraint types.
3365  */
3366 static void
3367 transformConstraintAttrs(CreateStmtContext *cxt, List *constraintList)
3368 {
3369 	Constraint *lastprimarycon = NULL;
3370 	bool		saw_deferrability = false;
3371 	bool		saw_initially = false;
3372 	ListCell   *clist;
3373 
3374 #define SUPPORTS_ATTRS(node)				\
3375 	((node) != NULL &&						\
3376 	 ((node)->contype == CONSTR_PRIMARY ||	\
3377 	  (node)->contype == CONSTR_UNIQUE ||	\
3378 	  (node)->contype == CONSTR_EXCLUSION || \
3379 	  (node)->contype == CONSTR_FOREIGN))
3380 
3381 	foreach(clist, constraintList)
3382 	{
3383 		Constraint *con = (Constraint *) lfirst(clist);
3384 
3385 		if (!IsA(con, Constraint))
3386 			elog(ERROR, "unrecognized node type: %d",
3387 				 (int) nodeTag(con));
3388 		switch (con->contype)
3389 		{
3390 			case CONSTR_ATTR_DEFERRABLE:
3391 				if (!SUPPORTS_ATTRS(lastprimarycon))
3392 					ereport(ERROR,
3393 							(errcode(ERRCODE_SYNTAX_ERROR),
3394 							 errmsg("misplaced DEFERRABLE clause"),
3395 							 parser_errposition(cxt->pstate, con->location)));
3396 				if (saw_deferrability)
3397 					ereport(ERROR,
3398 							(errcode(ERRCODE_SYNTAX_ERROR),
3399 							 errmsg("multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"),
3400 							 parser_errposition(cxt->pstate, con->location)));
3401 				saw_deferrability = true;
3402 				lastprimarycon->deferrable = true;
3403 				break;
3404 
3405 			case CONSTR_ATTR_NOT_DEFERRABLE:
3406 				if (!SUPPORTS_ATTRS(lastprimarycon))
3407 					ereport(ERROR,
3408 							(errcode(ERRCODE_SYNTAX_ERROR),
3409 							 errmsg("misplaced NOT DEFERRABLE clause"),
3410 							 parser_errposition(cxt->pstate, con->location)));
3411 				if (saw_deferrability)
3412 					ereport(ERROR,
3413 							(errcode(ERRCODE_SYNTAX_ERROR),
3414 							 errmsg("multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed"),
3415 							 parser_errposition(cxt->pstate, con->location)));
3416 				saw_deferrability = true;
3417 				lastprimarycon->deferrable = false;
3418 				if (saw_initially &&
3419 					lastprimarycon->initdeferred)
3420 					ereport(ERROR,
3421 							(errcode(ERRCODE_SYNTAX_ERROR),
3422 							 errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
3423 							 parser_errposition(cxt->pstate, con->location)));
3424 				break;
3425 
3426 			case CONSTR_ATTR_DEFERRED:
3427 				if (!SUPPORTS_ATTRS(lastprimarycon))
3428 					ereport(ERROR,
3429 							(errcode(ERRCODE_SYNTAX_ERROR),
3430 							 errmsg("misplaced INITIALLY DEFERRED clause"),
3431 							 parser_errposition(cxt->pstate, con->location)));
3432 				if (saw_initially)
3433 					ereport(ERROR,
3434 							(errcode(ERRCODE_SYNTAX_ERROR),
3435 							 errmsg("multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"),
3436 							 parser_errposition(cxt->pstate, con->location)));
3437 				saw_initially = true;
3438 				lastprimarycon->initdeferred = true;
3439 
3440 				/*
3441 				 * If only INITIALLY DEFERRED appears, assume DEFERRABLE
3442 				 */
3443 				if (!saw_deferrability)
3444 					lastprimarycon->deferrable = true;
3445 				else if (!lastprimarycon->deferrable)
3446 					ereport(ERROR,
3447 							(errcode(ERRCODE_SYNTAX_ERROR),
3448 							 errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
3449 							 parser_errposition(cxt->pstate, con->location)));
3450 				break;
3451 
3452 			case CONSTR_ATTR_IMMEDIATE:
3453 				if (!SUPPORTS_ATTRS(lastprimarycon))
3454 					ereport(ERROR,
3455 							(errcode(ERRCODE_SYNTAX_ERROR),
3456 							 errmsg("misplaced INITIALLY IMMEDIATE clause"),
3457 							 parser_errposition(cxt->pstate, con->location)));
3458 				if (saw_initially)
3459 					ereport(ERROR,
3460 							(errcode(ERRCODE_SYNTAX_ERROR),
3461 							 errmsg("multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed"),
3462 							 parser_errposition(cxt->pstate, con->location)));
3463 				saw_initially = true;
3464 				lastprimarycon->initdeferred = false;
3465 				break;
3466 
3467 			default:
3468 				/* Otherwise it's not an attribute */
3469 				lastprimarycon = con;
3470 				/* reset flags for new primary node */
3471 				saw_deferrability = false;
3472 				saw_initially = false;
3473 				break;
3474 		}
3475 	}
3476 }
3477 
3478 /*
3479  * Special handling of type definition for a column
3480  */
3481 static void
3482 transformColumnType(CreateStmtContext *cxt, ColumnDef *column)
3483 {
3484 	/*
3485 	 * All we really need to do here is verify that the type is valid,
3486 	 * including any collation spec that might be present.
3487 	 */
3488 	Type		ctype = typenameType(cxt->pstate, column->typeName, NULL);
3489 
3490 	if (column->collClause)
3491 	{
3492 		Form_pg_type typtup = (Form_pg_type) GETSTRUCT(ctype);
3493 
3494 		LookupCollation(cxt->pstate,
3495 						column->collClause->collname,
3496 						column->collClause->location);
3497 		/* Complain if COLLATE is applied to an uncollatable type */
3498 		if (!OidIsValid(typtup->typcollation))
3499 			ereport(ERROR,
3500 					(errcode(ERRCODE_DATATYPE_MISMATCH),
3501 					 errmsg("collations are not supported by type %s",
3502 							format_type_be(HeapTupleGetOid(ctype))),
3503 					 parser_errposition(cxt->pstate,
3504 										column->collClause->location)));
3505 	}
3506 
3507 	ReleaseSysCache(ctype);
3508 }
3509 
3510 
3511 /*
3512  * transformCreateSchemaStmt -
3513  *	  analyzes the CREATE SCHEMA statement
3514  *
3515  * Split the schema element list into individual commands and place
3516  * them in the result list in an order such that there are no forward
3517  * references (e.g. GRANT to a table created later in the list). Note
3518  * that the logic we use for determining forward references is
3519  * presently quite incomplete.
3520  *
3521  * SQL also allows constraints to make forward references, so thumb through
3522  * the table columns and move forward references to a posterior alter-table
3523  * command.
3524  *
3525  * The result is a list of parse nodes that still need to be analyzed ---
3526  * but we can't analyze the later commands until we've executed the earlier
3527  * ones, because of possible inter-object references.
3528  *
3529  * Note: this breaks the rules a little bit by modifying schema-name fields
3530  * within passed-in structs.  However, the transformation would be the same
3531  * if done over, so it should be all right to scribble on the input to this
3532  * extent.
3533  */
3534 List *
3535 transformCreateSchemaStmt(CreateSchemaStmt *stmt)
3536 {
3537 	CreateSchemaStmtContext cxt;
3538 	List	   *result;
3539 	ListCell   *elements;
3540 
3541 	cxt.stmtType = "CREATE SCHEMA";
3542 	cxt.schemaname = stmt->schemaname;
3543 	cxt.authrole = (RoleSpec *) stmt->authrole;
3544 	cxt.sequences = NIL;
3545 	cxt.tables = NIL;
3546 	cxt.views = NIL;
3547 	cxt.indexes = NIL;
3548 	cxt.triggers = NIL;
3549 	cxt.grants = NIL;
3550 
3551 	/*
3552 	 * Run through each schema element in the schema element list. Separate
3553 	 * statements by type, and do preliminary analysis.
3554 	 */
3555 	foreach(elements, stmt->schemaElts)
3556 	{
3557 		Node	   *element = lfirst(elements);
3558 
3559 		switch (nodeTag(element))
3560 		{
3561 			case T_CreateSeqStmt:
3562 				{
3563 					CreateSeqStmt *elp = (CreateSeqStmt *) element;
3564 
3565 					setSchemaName(cxt.schemaname, &elp->sequence->schemaname);
3566 					cxt.sequences = lappend(cxt.sequences, element);
3567 				}
3568 				break;
3569 
3570 			case T_CreateStmt:
3571 				{
3572 					CreateStmt *elp = (CreateStmt *) element;
3573 
3574 					setSchemaName(cxt.schemaname, &elp->relation->schemaname);
3575 
3576 					/*
3577 					 * XXX todo: deal with constraints
3578 					 */
3579 					cxt.tables = lappend(cxt.tables, element);
3580 				}
3581 				break;
3582 
3583 			case T_ViewStmt:
3584 				{
3585 					ViewStmt   *elp = (ViewStmt *) element;
3586 
3587 					setSchemaName(cxt.schemaname, &elp->view->schemaname);
3588 
3589 					/*
3590 					 * XXX todo: deal with references between views
3591 					 */
3592 					cxt.views = lappend(cxt.views, element);
3593 				}
3594 				break;
3595 
3596 			case T_IndexStmt:
3597 				{
3598 					IndexStmt  *elp = (IndexStmt *) element;
3599 
3600 					setSchemaName(cxt.schemaname, &elp->relation->schemaname);
3601 					cxt.indexes = lappend(cxt.indexes, element);
3602 				}
3603 				break;
3604 
3605 			case T_CreateTrigStmt:
3606 				{
3607 					CreateTrigStmt *elp = (CreateTrigStmt *) element;
3608 
3609 					setSchemaName(cxt.schemaname, &elp->relation->schemaname);
3610 					cxt.triggers = lappend(cxt.triggers, element);
3611 				}
3612 				break;
3613 
3614 			case T_GrantStmt:
3615 				cxt.grants = lappend(cxt.grants, element);
3616 				break;
3617 
3618 			default:
3619 				elog(ERROR, "unrecognized node type: %d",
3620 					 (int) nodeTag(element));
3621 		}
3622 	}
3623 
3624 	result = NIL;
3625 	result = list_concat(result, cxt.sequences);
3626 	result = list_concat(result, cxt.tables);
3627 	result = list_concat(result, cxt.views);
3628 	result = list_concat(result, cxt.indexes);
3629 	result = list_concat(result, cxt.triggers);
3630 	result = list_concat(result, cxt.grants);
3631 
3632 	return result;
3633 }
3634 
3635 /*
3636  * setSchemaName
3637  *		Set or check schema name in an element of a CREATE SCHEMA command
3638  */
3639 static void
3640 setSchemaName(char *context_schema, char **stmt_schema_name)
3641 {
3642 	if (*stmt_schema_name == NULL)
3643 		*stmt_schema_name = context_schema;
3644 	else if (strcmp(context_schema, *stmt_schema_name) != 0)
3645 		ereport(ERROR,
3646 				(errcode(ERRCODE_INVALID_SCHEMA_DEFINITION),
3647 				 errmsg("CREATE specifies a schema (%s) "
3648 						"different from the one being created (%s)",
3649 						*stmt_schema_name, context_schema)));
3650 }
3651 
3652 /*
3653  * transformPartitionCmd
3654  *		Analyze the ATTACH/DETACH PARTITION command
3655  *
3656  * In case of the ATTACH PARTITION command, cxt->partbound is set to the
3657  * transformed value of cmd->bound.
3658  */
3659 static void
3660 transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd)
3661 {
3662 	Relation	parentRel = cxt->rel;
3663 
3664 	switch (parentRel->rd_rel->relkind)
3665 	{
3666 		case RELKIND_PARTITIONED_TABLE:
3667 			/* transform the partition bound, if any */
3668 			Assert(RelationGetPartitionKey(parentRel) != NULL);
3669 			if (cmd->bound != NULL)
3670 				cxt->partbound = transformPartitionBound(cxt->pstate, parentRel,
3671 														 cmd->bound);
3672 			break;
3673 		case RELKIND_PARTITIONED_INDEX:
3674 			/* nothing to check */
3675 			break;
3676 		case RELKIND_RELATION:
3677 			/* the table must be partitioned */
3678 			ereport(ERROR,
3679 					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3680 					 errmsg("table \"%s\" is not partitioned",
3681 							RelationGetRelationName(parentRel))));
3682 			break;
3683 		case RELKIND_INDEX:
3684 			/* the index must be partitioned */
3685 			ereport(ERROR,
3686 					(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3687 					 errmsg("index \"%s\" is not partitioned",
3688 							RelationGetRelationName(parentRel))));
3689 			break;
3690 		default:
3691 			/* parser shouldn't let this case through */
3692 			elog(ERROR, "\"%s\" is not a partitioned table or index",
3693 				 RelationGetRelationName(parentRel));
3694 			break;
3695 	}
3696 }
3697 
3698 /*
3699  * transformPartitionBound
3700  *
3701  * Transform a partition bound specification
3702  */
3703 PartitionBoundSpec *
3704 transformPartitionBound(ParseState *pstate, Relation parent,
3705 						PartitionBoundSpec *spec)
3706 {
3707 	PartitionBoundSpec *result_spec;
3708 	PartitionKey key = RelationGetPartitionKey(parent);
3709 	char		strategy = get_partition_strategy(key);
3710 	int			partnatts = get_partition_natts(key);
3711 	List	   *partexprs = get_partition_exprs(key);
3712 
3713 	/* Avoid scribbling on input */
3714 	result_spec = copyObject(spec);
3715 
3716 	if (spec->is_default)
3717 	{
3718 		if (strategy == PARTITION_STRATEGY_HASH)
3719 			ereport(ERROR,
3720 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3721 					 errmsg("a hash-partitioned table may not have a default partition")));
3722 
3723 		/*
3724 		 * In case of the default partition, parser had no way to identify the
3725 		 * partition strategy. Assign the parent's strategy to the default
3726 		 * partition bound spec.
3727 		 */
3728 		result_spec->strategy = strategy;
3729 
3730 		return result_spec;
3731 	}
3732 
3733 	if (strategy == PARTITION_STRATEGY_HASH)
3734 	{
3735 		if (spec->strategy != PARTITION_STRATEGY_HASH)
3736 			ereport(ERROR,
3737 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3738 					 errmsg("invalid bound specification for a hash partition"),
3739 					 parser_errposition(pstate, exprLocation((Node *) spec))));
3740 
3741 		if (spec->modulus <= 0)
3742 			ereport(ERROR,
3743 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3744 					 errmsg("modulus for hash partition must be an integer value greater than zero")));
3745 
3746 		Assert(spec->remainder >= 0);
3747 
3748 		if (spec->remainder >= spec->modulus)
3749 			ereport(ERROR,
3750 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3751 					 errmsg("remainder for hash partition must be less than modulus")));
3752 	}
3753 	else if (strategy == PARTITION_STRATEGY_LIST)
3754 	{
3755 		ListCell   *cell;
3756 		char	   *colname;
3757 		Oid			coltype;
3758 		int32		coltypmod;
3759 
3760 		if (spec->strategy != PARTITION_STRATEGY_LIST)
3761 			ereport(ERROR,
3762 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3763 					 errmsg("invalid bound specification for a list partition"),
3764 					 parser_errposition(pstate, exprLocation((Node *) spec))));
3765 
3766 		/* Get the only column's name in case we need to output an error */
3767 		if (key->partattrs[0] != 0)
3768 			colname = get_attname(RelationGetRelid(parent),
3769 								  key->partattrs[0], false);
3770 		else
3771 			colname = deparse_expression((Node *) linitial(partexprs),
3772 										 deparse_context_for(RelationGetRelationName(parent),
3773 															 RelationGetRelid(parent)),
3774 										 false, false);
3775 		/* Need its type data too */
3776 		coltype = get_partition_col_typid(key, 0);
3777 		coltypmod = get_partition_col_typmod(key, 0);
3778 
3779 		result_spec->listdatums = NIL;
3780 		foreach(cell, spec->listdatums)
3781 		{
3782 			A_Const    *con = castNode(A_Const, lfirst(cell));
3783 			Const	   *value;
3784 			ListCell   *cell2;
3785 			bool		duplicate;
3786 
3787 			value = transformPartitionBoundValue(pstate, con,
3788 												 colname, coltype, coltypmod);
3789 
3790 			/* Don't add to the result if the value is a duplicate */
3791 			duplicate = false;
3792 			foreach(cell2, result_spec->listdatums)
3793 			{
3794 				Const	   *value2 = castNode(Const, lfirst(cell2));
3795 
3796 				if (equal(value, value2))
3797 				{
3798 					duplicate = true;
3799 					break;
3800 				}
3801 			}
3802 			if (duplicate)
3803 				continue;
3804 
3805 			result_spec->listdatums = lappend(result_spec->listdatums,
3806 											  value);
3807 		}
3808 	}
3809 	else if (strategy == PARTITION_STRATEGY_RANGE)
3810 	{
3811 		ListCell   *cell1,
3812 				   *cell2;
3813 		int			i,
3814 					j;
3815 
3816 		if (spec->strategy != PARTITION_STRATEGY_RANGE)
3817 			ereport(ERROR,
3818 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3819 					 errmsg("invalid bound specification for a range partition"),
3820 					 parser_errposition(pstate, exprLocation((Node *) spec))));
3821 
3822 		if (list_length(spec->lowerdatums) != partnatts)
3823 			ereport(ERROR,
3824 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3825 					 errmsg("FROM must specify exactly one value per partitioning column")));
3826 		if (list_length(spec->upperdatums) != partnatts)
3827 			ereport(ERROR,
3828 					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
3829 					 errmsg("TO must specify exactly one value per partitioning column")));
3830 
3831 		/*
3832 		 * Once we see MINVALUE or MAXVALUE for one column, the remaining
3833 		 * columns must be the same.
3834 		 */
3835 		validateInfiniteBounds(pstate, spec->lowerdatums);
3836 		validateInfiniteBounds(pstate, spec->upperdatums);
3837 
3838 		/* Transform all the constants */
3839 		i = j = 0;
3840 		result_spec->lowerdatums = result_spec->upperdatums = NIL;
3841 		forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums)
3842 		{
3843 			PartitionRangeDatum *ldatum = (PartitionRangeDatum *) lfirst(cell1);
3844 			PartitionRangeDatum *rdatum = (PartitionRangeDatum *) lfirst(cell2);
3845 			char	   *colname;
3846 			Oid			coltype;
3847 			int32		coltypmod;
3848 			A_Const    *con;
3849 			Const	   *value;
3850 
3851 			/* Get the column's name in case we need to output an error */
3852 			if (key->partattrs[i] != 0)
3853 				colname = get_attname(RelationGetRelid(parent),
3854 									  key->partattrs[i], false);
3855 			else
3856 			{
3857 				colname = deparse_expression((Node *) list_nth(partexprs, j),
3858 											 deparse_context_for(RelationGetRelationName(parent),
3859 																 RelationGetRelid(parent)),
3860 											 false, false);
3861 				++j;
3862 			}
3863 			/* Need its type data too */
3864 			coltype = get_partition_col_typid(key, i);
3865 			coltypmod = get_partition_col_typmod(key, i);
3866 
3867 			if (ldatum->value)
3868 			{
3869 				con = castNode(A_Const, ldatum->value);
3870 				value = transformPartitionBoundValue(pstate, con,
3871 													 colname,
3872 													 coltype, coltypmod);
3873 				if (value->constisnull)
3874 					ereport(ERROR,
3875 							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3876 							 errmsg("cannot specify NULL in range bound")));
3877 				ldatum = copyObject(ldatum);	/* don't scribble on input */
3878 				ldatum->value = (Node *) value;
3879 			}
3880 
3881 			if (rdatum->value)
3882 			{
3883 				con = castNode(A_Const, rdatum->value);
3884 				value = transformPartitionBoundValue(pstate, con,
3885 													 colname,
3886 													 coltype, coltypmod);
3887 				if (value->constisnull)
3888 					ereport(ERROR,
3889 							(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
3890 							 errmsg("cannot specify NULL in range bound")));
3891 				rdatum = copyObject(rdatum);	/* don't scribble on input */
3892 				rdatum->value = (Node *) value;
3893 			}
3894 
3895 			result_spec->lowerdatums = lappend(result_spec->lowerdatums,
3896 											   ldatum);
3897 			result_spec->upperdatums = lappend(result_spec->upperdatums,
3898 											   rdatum);
3899 
3900 			++i;
3901 		}
3902 	}
3903 	else
3904 		elog(ERROR, "unexpected partition strategy: %d", (int) strategy);
3905 
3906 	return result_spec;
3907 }
3908 
3909 /*
3910  * validateInfiniteBounds
3911  *
3912  * Check that a MAXVALUE or MINVALUE specification in a partition bound is
3913  * followed only by more of the same.
3914  */
3915 static void
3916 validateInfiniteBounds(ParseState *pstate, List *blist)
3917 {
3918 	ListCell   *lc;
3919 	PartitionRangeDatumKind kind = PARTITION_RANGE_DATUM_VALUE;
3920 
3921 	foreach(lc, blist)
3922 	{
3923 		PartitionRangeDatum *prd = castNode(PartitionRangeDatum, lfirst(lc));
3924 
3925 		if (kind == prd->kind)
3926 			continue;
3927 
3928 		switch (kind)
3929 		{
3930 			case PARTITION_RANGE_DATUM_VALUE:
3931 				kind = prd->kind;
3932 				break;
3933 
3934 			case PARTITION_RANGE_DATUM_MAXVALUE:
3935 				ereport(ERROR,
3936 						(errcode(ERRCODE_DATATYPE_MISMATCH),
3937 						 errmsg("every bound following MAXVALUE must also be MAXVALUE"),
3938 						 parser_errposition(pstate, exprLocation((Node *) prd))));
3939 				break;
3940 
3941 			case PARTITION_RANGE_DATUM_MINVALUE:
3942 				ereport(ERROR,
3943 						(errcode(ERRCODE_DATATYPE_MISMATCH),
3944 						 errmsg("every bound following MINVALUE must also be MINVALUE"),
3945 						 parser_errposition(pstate, exprLocation((Node *) prd))));
3946 				break;
3947 		}
3948 	}
3949 }
3950 
3951 /*
3952  * Transform one constant in a partition bound spec
3953  */
3954 static Const *
3955 transformPartitionBoundValue(ParseState *pstate, A_Const *con,
3956 							 const char *colName, Oid colType, int32 colTypmod)
3957 {
3958 	Node	   *value;
3959 
3960 	/* Make it into a Const */
3961 	value = (Node *) make_const(pstate, &con->val, con->location);
3962 
3963 	/* Coerce to correct type */
3964 	value = coerce_to_target_type(pstate,
3965 								  value, exprType(value),
3966 								  colType,
3967 								  colTypmod,
3968 								  COERCION_ASSIGNMENT,
3969 								  COERCE_IMPLICIT_CAST,
3970 								  -1);
3971 
3972 	if (value == NULL)
3973 		ereport(ERROR,
3974 				(errcode(ERRCODE_DATATYPE_MISMATCH),
3975 				 errmsg("specified value cannot be cast to type %s for column \"%s\"",
3976 						format_type_be(colType), colName),
3977 				 parser_errposition(pstate, con->location)));
3978 
3979 	/* Simplify the expression, in case we had a coercion */
3980 	if (!IsA(value, Const))
3981 		value = (Node *) expression_planner((Expr *) value);
3982 
3983 	/* Fail if we don't have a constant (i.e., non-immutable coercion) */
3984 	if (!IsA(value, Const))
3985 		ereport(ERROR,
3986 				(errcode(ERRCODE_DATATYPE_MISMATCH),
3987 				 errmsg("specified value cannot be cast to type %s for column \"%s\"",
3988 						format_type_be(colType), colName),
3989 				 errdetail("The cast requires a non-immutable conversion."),
3990 				 errhint("Try putting the literal value in single quotes."),
3991 				 parser_errposition(pstate, con->location)));
3992 
3993 	return (Const *) value;
3994 }
3995