keep_attstattargets_on_reindex_concurrently.patch
text/x-diff
Filename: keep_attstattargets_on_reindex_concurrently.patch
Type: text/x-diff
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/catalog/index.c | 18 | 8 |
| src/backend/catalog/toasting.c | 1 | 1 |
| src/backend/commands/indexcmds.c | 1 | 1 |
| src/include/catalog/index.h | 1 | 0 |
| src/test/regress/expected/alter_table.out | 21 | 0 |
| src/test/regress/sql/alter_table.sql | 9 | 0 |
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;