aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2024-03-17 12:38:27 +0100
committerPeter Eisentraut <peter@eisentraut.org>2024-03-17 12:38:27 +0100
commit6a004f1be87d34cfe51acf2fe2552d2b08a79273 (patch)
treedf26d6c12042def7b2af3d346ad9fe4c48167e44 /src
parentd939cb2fd612acde0304913213cfbdb01994e682 (diff)
downloadpostgresql-6a004f1be87d34cfe51acf2fe2552d2b08a79273.tar.gz
postgresql-6a004f1be87d34cfe51acf2fe2552d2b08a79273.zip
Add attstattarget to FormExtraData_pg_attribute
This allows setting attstattarget when a relation is created. We make use of this by having index_concurrently_create_copy() copy over the attstattarget values when the new index is created, instead of having index_concurrently_swap() fix it up later. Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/4da8d211-d54d-44b9-9847-f2a9f1184c76@eisentraut.org
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/heap.c5
-rw-r--r--src/backend/catalog/index.c97
-rw-r--r--src/backend/catalog/toasting.c2
-rw-r--r--src/backend/commands/indexcmds.c2
-rw-r--r--src/include/catalog/index.h1
-rw-r--r--src/include/catalog/pg_attribute.h1
6 files changed, 36 insertions, 72 deletions
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index de982c2c529..cc31909012d 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -758,18 +758,21 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation);
if (attrs_extra)
{
+ slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.value;
+ slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.isnull;
+
slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.value;
slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.isnull;
}
else
{
+ slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = true;
slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = true;
}
/*
* The remaining fields are not set for new columns.
*/
- slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = true;
slot[slotCount]->tts_isnull[Anum_pg_attribute_attacl - 1] = true;
slot[slotCount]->tts_isnull[Anum_pg_attribute_attfdwoptions - 1] = true;
slot[slotCount]->tts_isnull[Anum_pg_attribute_attmissingval - 1] = true;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 7e428f3eb79..b6a7c60e230 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -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);
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 21be81c1fb3..738bc46ae82 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -323,7 +323,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
list_make2("chunk_id", "chunk_seq"),
BTREE_AM_OID,
rel->rd_rel->reltablespace,
- collationIds, opclassIds, NULL, coloptions, (Datum) 0,
+ collationIds, opclassIds, NULL, 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 de89be8d759..7b20d103c86 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1210,7 +1210,7 @@ DefineIndex(Oid tableId,
stmt->oldNumber, indexInfo, indexColNames,
accessMethodId, tablespaceId,
collationIds, opclassIds, opclassOptions,
- 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 2ef8512dbff..2dea96f47c3 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -80,6 +80,7 @@ extern Oid index_create(Relation heapRelation,
const Oid *opclassIds,
const Datum *opclassOptions,
const int16 *coloptions,
+ const NullableDatum *stattargets,
Datum reloptions,
bits16 flags,
bits16 constr_flags,
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 1cc7a848f03..1c62b8bfcb5 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -218,6 +218,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
*/
typedef struct FormExtraData_pg_attribute
{
+ NullableDatum attstattarget;
NullableDatum attoptions;
} FormExtraData_pg_attribute;