@ -1197,7 +1197,8 @@ Oid
index_concurrently_create_copy ( Relation heapRelation , Oid oldIndexId , const char * newName )
index_concurrently_create_copy ( Relation heapRelation , Oid oldIndexId , const char * newName )
{
{
Relation indexRelation ;
Relation indexRelation ;
IndexInfo * indexInfo ;
IndexInfo * oldInfo ,
* newInfo ;
Oid newIndexId = InvalidOid ;
Oid newIndexId = InvalidOid ;
HeapTuple indexTuple ,
HeapTuple indexTuple ,
classTuple ;
classTuple ;
@ -1208,11 +1209,22 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char
int2vector * indcoloptions ;
int2vector * indcoloptions ;
bool isnull ;
bool isnull ;
List * indexColNames = NIL ;
List * indexColNames = NIL ;
List * indexExprs = NIL ;
List * indexPreds = NIL ;
indexRelation = index_open ( oldIndexId , RowExclusiveLock ) ;
indexRelation = index_open ( oldIndexId , RowExclusiveLock ) ;
/* New index uses the same index information as old index */
/* The new index needs some information from the old index */
indexInfo = BuildIndexInfo ( indexRelation ) ;
oldInfo = BuildIndexInfo ( indexRelation ) ;
/*
* Concurrent build of an index with exclusion constraints is not
* supported .
*/
if ( oldInfo - > ii_ExclusionOps ! = NULL )
ereport ( ERROR ,
( errcode ( ERRCODE_FEATURE_NOT_SUPPORTED ) ,
errmsg ( " concurrent index creation for exclusion constraints is not supported " ) ) ) ;
/* Get the array of class and column options IDs from index info */
/* Get the array of class and column options IDs from index info */
indexTuple = SearchSysCache1 ( INDEXRELID , ObjectIdGetDatum ( oldIndexId ) ) ;
indexTuple = SearchSysCache1 ( INDEXRELID , ObjectIdGetDatum ( oldIndexId ) ) ;
@ -1236,14 +1248,64 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char
Anum_pg_class_reloptions , & isnull ) ;
Anum_pg_class_reloptions , & isnull ) ;
/*
/*
* Extract the list of column names to be used for the index creation .
* Fetch the list of expressions and predicates directly from the
* catalogs . This cannot rely on the information from IndexInfo of the
* old index as these have been flattened for the planner .
*/
*/
for ( int i = 0 ; i < indexInfo - > ii_NumIndexAttrs ; i + + )
if ( oldInfo - > ii_Expressions ! = NIL )
{
Datum exprDatum ;
char * exprString ;
exprDatum = SysCacheGetAttr ( INDEXRELID , indexTuple ,
Anum_pg_index_indexprs , & isnull ) ;
Assert ( ! isnull ) ;
exprString = TextDatumGetCString ( exprDatum ) ;
indexExprs = ( List * ) stringToNode ( exprString ) ;
pfree ( exprString ) ;
}
if ( oldInfo - > ii_Predicate ! = NIL )
{
Datum predDatum ;
char * predString ;
predDatum = SysCacheGetAttr ( INDEXRELID , indexTuple ,
Anum_pg_index_indpred , & isnull ) ;
Assert ( ! isnull ) ;
predString = TextDatumGetCString ( predDatum ) ;
indexPreds = ( List * ) stringToNode ( predString ) ;
/* Also convert to implicit-AND format */
indexPreds = make_ands_implicit ( ( Expr * ) indexPreds ) ;
pfree ( predString ) ;
}
/*
* Build the index information for the new index . Note that rebuild of
* indexes with exclusion constraints is not supported , hence there is no
* need to fill all the ii_Exclusion * fields .
*/
newInfo = makeIndexInfo ( oldInfo - > ii_NumIndexAttrs ,
oldInfo - > ii_NumIndexKeyAttrs ,
oldInfo - > ii_Am ,
indexExprs ,
indexPreds ,
oldInfo - > ii_Unique ,
false , /* not ready for inserts */
true ) ;
/*
* Extract the list of column names and the column numbers for the new
* index information . All this information will be used for the index
* creation .
*/
for ( int i = 0 ; i < oldInfo - > ii_NumIndexAttrs ; i + + )
{
{
TupleDesc indexTupDesc = RelationGetDescr ( indexRelation ) ;
TupleDesc indexTupDesc = RelationGetDescr ( indexRelation ) ;
Form_pg_attribute att = TupleDescAttr ( indexTupDesc , i ) ;
Form_pg_attribute att = TupleDescAttr ( indexTupDesc , i ) ;
indexColNames = lappend ( indexColNames , NameStr ( att - > attname ) ) ;
indexColNames = lappend ( indexColNames , NameStr ( att - > attname ) ) ;
newInfo - > ii_IndexAttrNumbers [ i ] = oldInfo - > ii_IndexAttrNumbers [ i ] ;
}
}
/*
/*
@ -1259,7 +1321,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char
InvalidOid , /* parentIndexRelid */
InvalidOid , /* parentIndexRelid */
InvalidOid , /* parentConstraintId */
InvalidOid , /* parentConstraintId */
InvalidOid , /* relFileNode */
InvalidOid , /* relFileNode */
index Info,
new Info,
indexColNames ,
indexColNames ,
indexRelation - > rd_rel - > relam ,
indexRelation - > rd_rel - > relam ,
indexRelation - > rd_rel - > reltablespace ,
indexRelation - > rd_rel - > reltablespace ,