@@ -107,7 +107,7 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
107
107
const Oid * opclassIds );
108
108
static void InitializeAttributeOids (Relation indexRelation ,
109
109
int numatts , Oid indexoid );
110
- static void AppendAttributeTuples (Relation indexRelation , const Datum * attopts );
110
+ static void AppendAttributeTuples (Relation indexRelation , const Datum * attopts , const NullableDatum * stattargets );
111
111
static void UpdateIndexRelation (Oid indexoid , Oid heapoid ,
112
112
Oid parentIndexId ,
113
113
const IndexInfo * indexInfo ,
@@ -507,7 +507,7 @@ InitializeAttributeOids(Relation indexRelation,
507
507
* ----------------------------------------------------------------
508
508
*/
509
509
static void
510
- AppendAttributeTuples (Relation indexRelation , const Datum * attopts )
510
+ AppendAttributeTuples (Relation indexRelation , const Datum * attopts , const NullableDatum * stattargets )
511
511
{
512
512
Relation pg_attribute ;
513
513
CatalogIndexState indstate ;
@@ -524,6 +524,11 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
524
524
attrs_extra [i ].attoptions .value = attopts [i ];
525
525
else
526
526
attrs_extra [i ].attoptions .isnull = true;
527
+
528
+ if (stattargets )
529
+ attrs_extra [i ].attstattarget = stattargets [i ];
530
+ else
531
+ attrs_extra [i ].attstattarget .isnull = true;
527
532
}
528
533
}
529
534
@@ -730,6 +735,7 @@ index_create(Relation heapRelation,
730
735
const Oid * opclassIds ,
731
736
const Datum * opclassOptions ,
732
737
const int16 * coloptions ,
738
+ const NullableDatum * stattargets ,
733
739
Datum reloptions ,
734
740
bits16 flags ,
735
741
bits16 constr_flags ,
@@ -1024,7 +1030,7 @@ index_create(Relation heapRelation,
1024
1030
/*
1025
1031
* append ATTRIBUTE tuples for the index
1026
1032
*/
1027
- AppendAttributeTuples (indexRelation , opclassOptions );
1033
+ AppendAttributeTuples (indexRelation , opclassOptions , stattargets );
1028
1034
1029
1035
/* ----------------
1030
1036
* update pg_index
@@ -1303,6 +1309,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
1303
1309
Datum * opclassOptions ;
1304
1310
oidvector * indclass ;
1305
1311
int2vector * indcoloptions ;
1312
+ NullableDatum * stattargets ;
1306
1313
bool isnull ;
1307
1314
List * indexColNames = NIL ;
1308
1315
List * indexExprs = NIL ;
@@ -1407,6 +1414,23 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
1407
1414
for (int i = 0 ; i < newInfo -> ii_NumIndexAttrs ; i ++ )
1408
1415
opclassOptions [i ] = get_attoptions (oldIndexId , i + 1 );
1409
1416
1417
+ /* Extract statistic targets for each attribute */
1418
+ stattargets = palloc0_array (NullableDatum , newInfo -> ii_NumIndexAttrs );
1419
+ for (int i = 0 ; i < newInfo -> ii_NumIndexAttrs ; i ++ )
1420
+ {
1421
+ HeapTuple tp ;
1422
+ Datum dat ;
1423
+
1424
+ tp = SearchSysCache2 (ATTNUM , ObjectIdGetDatum (oldIndexId ), Int16GetDatum (i + 1 ));
1425
+ if (!HeapTupleIsValid (tp ))
1426
+ elog (ERROR , "cache lookup failed for attribute %d of relation %u" ,
1427
+ i + 1 , oldIndexId );
1428
+ dat = SysCacheGetAttr (ATTNUM , tp , Anum_pg_attribute_attstattarget , & isnull );
1429
+ ReleaseSysCache (tp );
1430
+ stattargets [i ].value = dat ;
1431
+ stattargets [i ].isnull = isnull ;
1432
+ }
1433
+
1410
1434
/*
1411
1435
* Now create the new index.
1412
1436
*
@@ -1428,6 +1452,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
1428
1452
indclass -> values ,
1429
1453
opclassOptions ,
1430
1454
indcoloptions -> values ,
1455
+ stattargets ,
1431
1456
reloptionsDatum ,
1432
1457
INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT ,
1433
1458
0 ,
@@ -1771,72 +1796,6 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
1771
1796
/* Copy data of pg_statistic from the old index to the new one */
1772
1797
CopyStatistics (oldIndexId , newIndexId );
1773
1798
1774
- /* Copy pg_attribute.attstattarget for each index attribute */
1775
- {
1776
- HeapTuple attrTuple ;
1777
- Relation pg_attribute ;
1778
- SysScanDesc scan ;
1779
- ScanKeyData key [1 ];
1780
-
1781
- pg_attribute = table_open (AttributeRelationId , RowExclusiveLock );
1782
- ScanKeyInit (& key [0 ],
1783
- Anum_pg_attribute_attrelid ,
1784
- BTEqualStrategyNumber , F_OIDEQ ,
1785
- ObjectIdGetDatum (newIndexId ));
1786
- scan = systable_beginscan (pg_attribute , AttributeRelidNumIndexId ,
1787
- true, NULL , 1 , key );
1788
-
1789
- while (HeapTupleIsValid ((attrTuple = systable_getnext (scan ))))
1790
- {
1791
- Form_pg_attribute att = (Form_pg_attribute ) GETSTRUCT (attrTuple );
1792
- HeapTuple tp ;
1793
- Datum dat ;
1794
- bool isnull ;
1795
- Datum repl_val [Natts_pg_attribute ];
1796
- bool repl_null [Natts_pg_attribute ];
1797
- bool repl_repl [Natts_pg_attribute ];
1798
- HeapTuple newTuple ;
1799
-
1800
- /* Ignore dropped columns */
1801
- if (att -> attisdropped )
1802
- continue ;
1803
-
1804
- /*
1805
- * Get attstattarget from the old index and refresh the new value.
1806
- */
1807
- tp = SearchSysCache2 (ATTNUM , ObjectIdGetDatum (oldIndexId ), Int16GetDatum (att -> attnum ));
1808
- if (!HeapTupleIsValid (tp ))
1809
- elog (ERROR , "cache lookup failed for attribute %d of relation %u" ,
1810
- att -> attnum , oldIndexId );
1811
- dat = SysCacheGetAttr (ATTNUM , tp , Anum_pg_attribute_attstattarget , & isnull );
1812
- ReleaseSysCache (tp );
1813
-
1814
- /*
1815
- * No need for a refresh if old index value is null. (All new
1816
- * index values are null at this point.)
1817
- */
1818
- if (isnull )
1819
- continue ;
1820
-
1821
- memset (repl_val , 0 , sizeof (repl_val ));
1822
- memset (repl_null , false, sizeof (repl_null ));
1823
- memset (repl_repl , false, sizeof (repl_repl ));
1824
-
1825
- repl_repl [Anum_pg_attribute_attstattarget - 1 ] = true;
1826
- repl_val [Anum_pg_attribute_attstattarget - 1 ] = dat ;
1827
-
1828
- newTuple = heap_modify_tuple (attrTuple ,
1829
- RelationGetDescr (pg_attribute ),
1830
- repl_val , repl_null , repl_repl );
1831
- CatalogTupleUpdate (pg_attribute , & newTuple -> t_self , newTuple );
1832
-
1833
- heap_freetuple (newTuple );
1834
- }
1835
-
1836
- systable_endscan (scan );
1837
- table_close (pg_attribute , RowExclusiveLock );
1838
- }
1839
-
1840
1799
/* Close relations */
1841
1800
table_close (pg_class , RowExclusiveLock );
1842
1801
table_close (pg_index , RowExclusiveLock );
0 commit comments