@@ -680,19 +680,25 @@ UpdateIndexRelation(Oid indexoid,
680680 * classObjectId: array of index opclass OIDs, one per index column
681681 * coloptions: array of per-index-column indoption settings
682682 * reloptions: AM-specific options
683- * isprimary: index is a PRIMARY KEY
684- * isconstraint: index is owned by PRIMARY KEY, UNIQUE, or EXCLUSION constraint
685- * deferrable: constraint is DEFERRABLE
686- * initdeferred: constraint is INITIALLY DEFERRED
683+ * flags: bitmask that can include any combination of these bits:
684+ *INDEX_CREATE_IS_PRIMARY
685+ *the index is a primary key
686+ *INDEX_CREATE_ADD_CONSTRAINT:
687+ *invoke index_constraint_create also
688+ *INDEX_CREATE_SKIP_BUILD:
689+ *skip the index_build() step for the moment; caller must do it
690+ *later (typically via reindex_index())
691+ *INDEX_CREATE_CONCURRENT:
692+ *do not lock the table against writers. The index will be
693+ *marked "invalid" and the caller must take additional steps
694+ *to fix it up.
695+ *INDEX_CREATE_IF_NOT_EXISTS:
696+ *do not throw an error if a relation with the same name
697+ *already exists.
698+ * constr_flags: flags passed to index_constraint_create
699+ *(only if INDEX_CREATE_ADD_CONSTRAINT is set)
687700 * allow_system_table_mods: allow table to be a system catalog
688- * skip_build: true to skip the index_build() step for the moment; caller
689- *must do it later (typically via reindex_index())
690- * concurrent: if true, do not lock the table against writers. The index
691- *will be marked "invalid" and the caller must take additional steps
692- *to fix it up.
693701 * is_internal: if true, post creation hook for new index
694- * if_not_exists: if true, do not throw an error if a relation with
695- *the same name already exists.
696702 *
697703 * Returns the OID of the created index.
698704 */
@@ -709,15 +715,10 @@ index_create(Relation heapRelation,
709715Oid * classObjectId ,
710716int16 * coloptions ,
711717Datum reloptions ,
712- bool isprimary ,
713- bool isconstraint ,
714- bool deferrable ,
715- bool initdeferred ,
718+ bits16 flags ,
719+ bits16 constr_flags ,
716720bool allow_system_table_mods ,
717- bool skip_build ,
718- bool concurrent ,
719- bool is_internal ,
720- bool if_not_exists )
721+ bool is_internal )
721722{
722723Oid heapRelationId = RelationGetRelid (heapRelation );
723724Relation pg_class ;
@@ -729,6 +730,12 @@ index_create(Relation heapRelation,
729730Oid namespaceId ;
730731int i ;
731732char relpersistence ;
733+ bool isprimary = (flags & INDEX_CREATE_IS_PRIMARY )!= 0 ;
734+ bool concurrent = (flags & INDEX_CREATE_CONCURRENT )!= 0 ;
735+
736+ /* constraint flags can only be set when a constraint is requested */
737+ Assert ((constr_flags == 0 )||
738+ ((flags & INDEX_CREATE_ADD_CONSTRAINT )!= 0 ));
732739
733740is_exclusion = (indexInfo -> ii_ExclusionOps != NULL );
734741
@@ -794,7 +801,7 @@ index_create(Relation heapRelation,
794801
795802if (get_relname_relid (indexRelationName ,namespaceId ))
796803{
797- if (if_not_exists )
804+ if (( flags & INDEX_CREATE_IF_NOT_EXISTS ) != 0 )
798805{
799806ereport (NOTICE ,
800807(errcode (ERRCODE_DUPLICATE_TABLE ),
@@ -917,7 +924,7 @@ index_create(Relation heapRelation,
917924UpdateIndexRelation (indexRelationId ,heapRelationId ,indexInfo ,
918925collationObjectId ,classObjectId ,coloptions ,
919926isprimary ,is_exclusion ,
920- ! deferrable ,
927+ ( constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE ) == 0 ,
921928!concurrent );
922929
923930/*
@@ -943,7 +950,7 @@ index_create(Relation heapRelation,
943950myself .objectId = indexRelationId ;
944951myself .objectSubId = 0 ;
945952
946- if (isconstraint )
953+ if (( flags & INDEX_CREATE_ADD_CONSTRAINT ) != 0 )
947954{
948955char constraintType ;
949956
@@ -964,11 +971,7 @@ index_create(Relation heapRelation,
964971indexInfo ,
965972indexRelationName ,
966973constraintType ,
967- deferrable ,
968- initdeferred ,
969- false,/* already marked primary */
970- false,/* pg_index entry is OK */
971- false,/* no old dependencies */
974+ constr_flags ,
972975allow_system_table_mods ,
973976is_internal );
974977}
@@ -1005,10 +1008,6 @@ index_create(Relation heapRelation,
10051008
10061009recordDependencyOn (& myself ,& referenced ,DEPENDENCY_AUTO );
10071010}
1008-
1009- /* Non-constraint indexes can't be deferrable */
1010- Assert (!deferrable );
1011- Assert (!initdeferred );
10121011}
10131012
10141013/* Store dependency on collations */
@@ -1059,9 +1058,7 @@ index_create(Relation heapRelation,
10591058else
10601059{
10611060/* Bootstrap mode - assert we weren't asked for constraint support */
1062- Assert (!isconstraint );
1063- Assert (!deferrable );
1064- Assert (!initdeferred );
1061+ Assert ((flags & INDEX_CREATE_ADD_CONSTRAINT )== 0 );
10651062}
10661063
10671064/* Post creation hook for new index */
@@ -1089,15 +1086,16 @@ index_create(Relation heapRelation,
10891086 * If this is bootstrap (initdb) time, then we don't actually fill in the
10901087 * index yet. We'll be creating more indexes and classes later, so we
10911088 * delay filling them in until just before we're done with bootstrapping.
1092- * Similarly, if the caller specified skip_build then filling the index is
1093- * delayed till later (ALTER TABLE can save work in some cases with this).
1094- * Otherwise, we call the AM routine that constructs the index.
1089+ * Similarly, if the caller specified to skip the build then filling the
1090+ * index is delayed till later (ALTER TABLE can save work in some cases
1091+ * with this). Otherwise, we call the AM routine that constructs the
1092+ * index.
10951093 */
10961094if (IsBootstrapProcessingMode ())
10971095{
10981096index_register (heapRelationId ,indexRelationId ,indexInfo );
10991097}
1100- else if (skip_build )
1098+ else if (( flags & INDEX_CREATE_SKIP_BUILD ) != 0 )
11011099{
11021100/*
11031101 * Caller is responsible for filling the index later on. However,
@@ -1137,12 +1135,13 @@ index_create(Relation heapRelation,
11371135 * constraintName: what it say (generally, should match name of index)
11381136 * constraintType: one of CONSTRAINT_PRIMARY, CONSTRAINT_UNIQUE, or
11391137 *CONSTRAINT_EXCLUSION
1140- * deferrable: constraint is DEFERRABLE
1141- * initdeferred: constraint is INITIALLY DEFERRED
1142- * mark_as_primary: if true, set flags to mark index as primary key
1143- * update_pgindex: if true, update pg_index row (else caller's done that)
1144- * remove_old_dependencies: if true, remove existing dependencies of index
1145- *on table's columns
1138+ * flags: bitmask that can include any combination of these bits:
1139+ *INDEX_CONSTR_CREATE_MARK_AS_PRIMARY: index is a PRIMARY KEY
1140+ *INDEX_CONSTR_CREATE_DEFERRABLE: constraint is DEFERRABLE
1141+ *INDEX_CONSTR_CREATE_INIT_DEFERRED: constraint is INITIALLY DEFERRED
1142+ *INDEX_CONSTR_CREATE_UPDATE_INDEX: update the pg_index row
1143+ *INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS: remove existing dependencies
1144+ *of index on table's columns
11461145 * allow_system_table_mods: allow table to be a system catalog
11471146 * is_internal: index is constructed due to internal process
11481147 */
@@ -1152,18 +1151,21 @@ index_constraint_create(Relation heapRelation,
11521151IndexInfo * indexInfo ,
11531152const char * constraintName ,
11541153char constraintType ,
1155- bool deferrable ,
1156- bool initdeferred ,
1157- bool mark_as_primary ,
1158- bool update_pgindex ,
1159- bool remove_old_dependencies ,
1154+ bits16 constr_flags ,
11601155bool allow_system_table_mods ,
11611156bool is_internal )
11621157{
11631158Oid namespaceId = RelationGetNamespace (heapRelation );
11641159ObjectAddress myself ,
11651160referenced ;
11661161Oid conOid ;
1162+ bool deferrable ;
1163+ bool initdeferred ;
1164+ bool mark_as_primary ;
1165+
1166+ deferrable = (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE )!= 0 ;
1167+ initdeferred = (constr_flags & INDEX_CONSTR_CREATE_INIT_DEFERRED )!= 0 ;
1168+ mark_as_primary = (constr_flags & INDEX_CONSTR_CREATE_MARK_AS_PRIMARY )!= 0 ;
11671169
11681170/* constraint creation support doesn't work while bootstrapping */
11691171Assert (!IsBootstrapProcessingMode ());
@@ -1190,7 +1192,7 @@ index_constraint_create(Relation heapRelation,
11901192 * has any expressions or predicate, but we'd never be turning such an
11911193 * index into a UNIQUE or PRIMARY KEY constraint.
11921194 */
1193- if (remove_old_dependencies )
1195+ if (constr_flags & INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS )
11941196deleteDependencyRecordsForClass (RelationRelationId ,indexRelationId ,
11951197RelationRelationId ,DEPENDENCY_AUTO );
11961198
@@ -1295,7 +1297,8 @@ index_constraint_create(Relation heapRelation,
12951297 * is a risk that concurrent readers of the table will miss seeing this
12961298 * index at all.
12971299 */
1298- if (update_pgindex && (mark_as_primary || deferrable ))
1300+ if ((constr_flags & INDEX_CONSTR_CREATE_UPDATE_INDEX )&&
1301+ (mark_as_primary || deferrable ))
12991302{
13001303Relation pg_index ;
13011304HeapTuple indexTuple ;