diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 5a70fe4d2c..b4adb32af0 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -107,7 +107,8 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation, List *indexColNames, Oid accessMethodObjectId, Oid *collationObjectId, - Oid *classObjectId); + Oid *classObjectId, + int32 *attstattargets); static void InitializeAttributeOids(Relation indexRelation, int numatts, Oid indexoid); static void AppendAttributeTuples(Relation indexRelation, Datum *attopts); @@ -272,7 +273,8 @@ ConstructTupleDescriptor(Relation heapRelation, List *indexColNames, Oid accessMethodObjectId, Oid *collationObjectId, - Oid *classObjectId) + Oid *classObjectId, + int32 *attstattargets) { int numatts = indexInfo->ii_NumIndexAttrs; int numkeyatts = indexInfo->ii_NumIndexKeyAttrs; @@ -310,12 +312,14 @@ ConstructTupleDescriptor(Relation heapRelation, MemSet(to, 0, ATTRIBUTE_FIXED_PART_SIZE); to->attnum = i + 1; - to->attstattarget = -1; to->attcacheoff = -1; to->attislocal = true; to->attcollation = (i < numkeyatts) ? collationObjectId[i] : InvalidOid; - + if(attstattargets != NULL) + to->attstattarget = attstattargets[i]; + else + to->attstattarget = -1; /* * Set the attribute name as specified by caller. */ @@ -697,6 +701,7 @@ index_create(Relation heapRelation, Oid *collationObjectId, Oid *classObjectId, int16 *coloptions, + int32 *colstattargets, Datum reloptions, bits16 flags, bits16 constr_flags, @@ -882,7 +887,8 @@ index_create(Relation heapRelation, indexColNames, accessMethodObjectId, collationObjectId, - classObjectId); + classObjectId, + colstattargets); /* * Allocate an OID for the index, unless we were told what to use. @@ -1413,11 +1419,13 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, optionDatum; oidvector *indclass; int2vector *indcoloptions; + int32 *colstattargets; bool isnull; List *indexColNames = NIL; List *indexExprs = NIL; List *indexPreds = NIL; + indexRelation = index_open(oldIndexId, RowExclusiveLock); /* The new index needs some information from the old index */ @@ -1501,10 +1509,11 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, true); /* - * Extract the list of column names and the column numbers for the new + * Extract the list of column names, column numbers and stattargets for the new * index information. All this information will be used for the index * creation. */ + colstattargets = palloc(sizeof(int32) * oldInfo->ii_NumIndexAttrs); for (int i = 0; i < oldInfo->ii_NumIndexAttrs; i++) { TupleDesc indexTupDesc = RelationGetDescr(indexRelation); @@ -1512,8 +1521,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, indexColNames = lappend(indexColNames, NameStr(att->attname)); newInfo->ii_IndexAttrNumbers[i] = oldInfo->ii_IndexAttrNumbers[i]; + colstattargets[i] = att->attstattarget; } - /* * Now create the new index. * @@ -1534,13 +1543,14 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, indexRelation->rd_indcollation, indclass->values, indcoloptions->values, + colstattargets, optionDatum, INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT, 0, true, /* allow table to be a system catalog? */ false, /* is_internal? */ NULL); - + pfree(colstattargets); /* Close the relations used and clean up */ index_close(indexRelation, NoLock); ReleaseSysCache(indexTuple); diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index d7b806020d..09c1be3611 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -313,7 +313,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, list_make2("chunk_id", "chunk_seq"), BTREE_AM_OID, rel->rd_rel->reltablespace, - collationObjectId, classObjectId, coloptions, (Datum) 0, + collationObjectId, classObjectId, coloptions, NULL, (Datum) 0, INDEX_CREATE_IS_PRIMARY, 0, true, true, NULL); table_close(toast_rel, NoLock); diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 127ba7835d..6eba68c7ba 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -1140,7 +1140,7 @@ DefineIndex(Oid relationId, stmt->oldNode, indexInfo, indexColNames, accessMethodId, tablespaceId, collationObjectId, classObjectId, - coloptions, reloptions, + coloptions, NULL, reloptions, flags, constr_flags, allowSystemTableMods, !check_rights, &createdConstraintId); diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index e22d506436..bf9bc6bcef 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -79,6 +79,7 @@ extern Oid index_create(Relation heapRelation, Oid *collationObjectId, Oid *classObjectId, int16 *coloptions, + int32 *colstattargets, Datum reloptions, bits16 flags, bits16 constr_flags, diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 0ce6ee4622..a9140bc837 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -113,6 +113,27 @@ ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000; b | cstring | yes | b | plain | btree, for table "public.attmp" +-- Check we keep statistics after REINDEX and REINDEX CONCURRENTLY +REINDEX INDEX attmp_idx; +\d+ attmp_idx + Index "public.attmp_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+------------------+------+------------+---------+-------------- + a | integer | yes | a | plain | + expr | double precision | yes | (d + e) | plain | 1000 + b | cstring | yes | b | plain | +btree, for table "public.attmp" + +REINDEX INDEX CONCURRENTLY attmp_idx; +\d+ attmp_idx + Index "public.attmp_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+------------------+------+------------+---------+-------------- + a | integer | yes | a | plain | + expr | double precision | yes | (d + e) | plain | 1000 + b | cstring | yes | b | plain | +btree, for table "public.attmp" + ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000; ERROR: cannot alter statistics on non-expression column "b" of index "attmp_idx" HINT: Alter statistics on table column instead. diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 4cc55d8525..36b24bfeb0 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -150,6 +150,15 @@ ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000; \d+ attmp_idx +-- Check we keep statistics after REINDEX and REINDEX CONCURRENTLY +REINDEX INDEX attmp_idx; + +\d+ attmp_idx + +REINDEX INDEX CONCURRENTLY attmp_idx; + +\d+ attmp_idx + ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000; ALTER INDEX attmp_idx ALTER COLUMN 4 SET STATISTICS 1000;