@ -107,7 +107,7 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
const Oid * opclassIds ) ;
static void InitializeAttributeOids ( Relation indexRelation ,
int numatts , Oid indexoid ) ;
static void AppendAttributeTuples ( Relation indexRelation , const Datum * attopts ) ;
static void AppendAttributeTuples ( Relation indexRelation , const Datum * attopts , const NullableDatum * stattargets ) ;
static void UpdateIndexRelation ( Oid indexoid , Oid heapoid ,
Oid parentIndexId ,
const IndexInfo * indexInfo ,
@ -507,7 +507,7 @@ InitializeAttributeOids(Relation indexRelation,
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
static void
AppendAttributeTuples ( Relation indexRelation , const Datum * attopts )
AppendAttributeTuples ( Relation indexRelation , const Datum * attopts , const NullableDatum * stattargets )
{
Relation pg_attribute ;
CatalogIndexState indstate ;
@ -524,6 +524,11 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
attrs_extra [ i ] . attoptions . value = attopts [ i ] ;
else
attrs_extra [ i ] . attoptions . isnull = true ;
if ( stattargets )
attrs_extra [ i ] . attstattarget = stattargets [ i ] ;
else
attrs_extra [ i ] . attstattarget . isnull = true ;
}
}
@ -730,6 +735,7 @@ index_create(Relation heapRelation,
const Oid * opclassIds ,
const Datum * opclassOptions ,
const int16 * coloptions ,
const NullableDatum * stattargets ,
Datum reloptions ,
bits16 flags ,
bits16 constr_flags ,
@ -1024,7 +1030,7 @@ index_create(Relation heapRelation,
/*
* append ATTRIBUTE tuples for the index
*/
AppendAttributeTuples ( indexRelation , opclassOptions ) ;
AppendAttributeTuples ( indexRelation , opclassOptions , stattargets ) ;
/* ----------------
* update pg_index
@ -1303,6 +1309,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
Datum * opclassOptions ;
oidvector * indclass ;
int2vector * indcoloptions ;
NullableDatum * stattargets ;
bool isnull ;
List * indexColNames = NIL ;
List * indexExprs = NIL ;
@ -1407,6 +1414,23 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
for ( int i = 0 ; i < newInfo - > ii_NumIndexAttrs ; i + + )
opclassOptions [ i ] = get_attoptions ( oldIndexId , i + 1 ) ;
/* Extract statistic targets for each attribute */
stattargets = palloc0_array ( NullableDatum , newInfo - > ii_NumIndexAttrs ) ;
for ( int i = 0 ; i < newInfo - > ii_NumIndexAttrs ; i + + )
{
HeapTuple tp ;
Datum dat ;
tp = SearchSysCache2 ( ATTNUM , ObjectIdGetDatum ( oldIndexId ) , Int16GetDatum ( i + 1 ) ) ;
if ( ! HeapTupleIsValid ( tp ) )
elog ( ERROR , " cache lookup failed for attribute %d of relation %u " ,
i + 1 , oldIndexId ) ;
dat = SysCacheGetAttr ( ATTNUM , tp , Anum_pg_attribute_attstattarget , & isnull ) ;
ReleaseSysCache ( tp ) ;
stattargets [ i ] . value = dat ;
stattargets [ i ] . isnull = isnull ;
}
/*
* Now create the new index .
*
@ -1428,6 +1452,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
indclass - > values ,
opclassOptions ,
indcoloptions - > values ,
stattargets ,
reloptionsDatum ,
INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT ,
0 ,
@ -1771,72 +1796,6 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
/* Copy data of pg_statistic from the old index to the new one */
CopyStatistics ( oldIndexId , newIndexId ) ;
/* Copy pg_attribute.attstattarget for each index attribute */
{
HeapTuple attrTuple ;
Relation pg_attribute ;
SysScanDesc scan ;
ScanKeyData key [ 1 ] ;
pg_attribute = table_open ( AttributeRelationId , RowExclusiveLock ) ;
ScanKeyInit ( & key [ 0 ] ,
Anum_pg_attribute_attrelid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( newIndexId ) ) ;
scan = systable_beginscan ( pg_attribute , AttributeRelidNumIndexId ,
true , NULL , 1 , key ) ;
while ( HeapTupleIsValid ( ( attrTuple = systable_getnext ( scan ) ) ) )
{
Form_pg_attribute att = ( Form_pg_attribute ) GETSTRUCT ( attrTuple ) ;
HeapTuple tp ;
Datum dat ;
bool isnull ;
Datum repl_val [ Natts_pg_attribute ] ;
bool repl_null [ Natts_pg_attribute ] ;
bool repl_repl [ Natts_pg_attribute ] ;
HeapTuple newTuple ;
/* Ignore dropped columns */
if ( att - > attisdropped )
continue ;
/*
* Get attstattarget from the old index and refresh the new value .
*/
tp = SearchSysCache2 ( ATTNUM , ObjectIdGetDatum ( oldIndexId ) , Int16GetDatum ( att - > attnum ) ) ;
if ( ! HeapTupleIsValid ( tp ) )
elog ( ERROR , " cache lookup failed for attribute %d of relation %u " ,
att - > attnum , oldIndexId ) ;
dat = SysCacheGetAttr ( ATTNUM , tp , Anum_pg_attribute_attstattarget , & isnull ) ;
ReleaseSysCache ( tp ) ;
/*
* No need for a refresh if old index value is null . ( All new
* index values are null at this point . )
*/
if ( isnull )
continue ;
memset ( repl_val , 0 , sizeof ( repl_val ) ) ;
memset ( repl_null , false , sizeof ( repl_null ) ) ;
memset ( repl_repl , false , sizeof ( repl_repl ) ) ;
repl_repl [ Anum_pg_attribute_attstattarget - 1 ] = true ;
repl_val [ Anum_pg_attribute_attstattarget - 1 ] = dat ;
newTuple = heap_modify_tuple ( attrTuple ,
RelationGetDescr ( pg_attribute ) ,
repl_val , repl_null , repl_repl ) ;
CatalogTupleUpdate ( pg_attribute , & newTuple - > t_self , newTuple ) ;
heap_freetuple ( newTuple ) ;
}
systable_endscan ( scan ) ;
table_close ( pg_attribute , RowExclusiveLock ) ;
}
/* Close relations */
table_close ( pg_class , RowExclusiveLock ) ;
table_close ( pg_index , RowExclusiveLock ) ;