Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6a004f1

Browse files
committed
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
1 parent d939cb2 commit 6a004f1

File tree

6 files changed

+36
-72
lines changed

6 files changed

+36
-72
lines changed

src/backend/catalog/heap.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,18 +758,21 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
758758
slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation);
759759
if (attrs_extra)
760760
{
761+
slot[slotCount]->tts_values[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.value;
762+
slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = attrs_extra->attstattarget.isnull;
763+
761764
slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.value;
762765
slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.isnull;
763766
}
764767
else
765768
{
769+
slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = true;
766770
slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = true;
767771
}
768772

769773
/*
770774
* The remaining fields are not set for new columns.
771775
*/
772-
slot[slotCount]->tts_isnull[Anum_pg_attribute_attstattarget - 1] = true;
773776
slot[slotCount]->tts_isnull[Anum_pg_attribute_attacl - 1] = true;
774777
slot[slotCount]->tts_isnull[Anum_pg_attribute_attfdwoptions - 1] = true;
775778
slot[slotCount]->tts_isnull[Anum_pg_attribute_attmissingval - 1] = true;

src/backend/catalog/index.c

Lines changed: 28 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
107107
const Oid *opclassIds);
108108
static void InitializeAttributeOids(Relation indexRelation,
109109
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);
111111
static void UpdateIndexRelation(Oid indexoid, Oid heapoid,
112112
Oid parentIndexId,
113113
const IndexInfo *indexInfo,
@@ -507,7 +507,7 @@ InitializeAttributeOids(Relation indexRelation,
507507
* ----------------------------------------------------------------
508508
*/
509509
static void
510-
AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
510+
AppendAttributeTuples(Relation indexRelation, const Datum *attopts, const NullableDatum *stattargets)
511511
{
512512
Relation pg_attribute;
513513
CatalogIndexState indstate;
@@ -524,6 +524,11 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
524524
attrs_extra[i].attoptions.value = attopts[i];
525525
else
526526
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;
527532
}
528533
}
529534

@@ -730,6 +735,7 @@ index_create(Relation heapRelation,
730735
const Oid *opclassIds,
731736
const Datum *opclassOptions,
732737
const int16 *coloptions,
738+
const NullableDatum *stattargets,
733739
Datum reloptions,
734740
bits16 flags,
735741
bits16 constr_flags,
@@ -1024,7 +1030,7 @@ index_create(Relation heapRelation,
10241030
/*
10251031
* append ATTRIBUTE tuples for the index
10261032
*/
1027-
AppendAttributeTuples(indexRelation, opclassOptions);
1033+
AppendAttributeTuples(indexRelation, opclassOptions, stattargets);
10281034

10291035
/* ----------------
10301036
* update pg_index
@@ -1303,6 +1309,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
13031309
Datum *opclassOptions;
13041310
oidvector *indclass;
13051311
int2vector *indcoloptions;
1312+
NullableDatum *stattargets;
13061313
bool isnull;
13071314
List *indexColNames = NIL;
13081315
List *indexExprs = NIL;
@@ -1407,6 +1414,23 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
14071414
for (int i = 0; i < newInfo->ii_NumIndexAttrs; i++)
14081415
opclassOptions[i] = get_attoptions(oldIndexId, i + 1);
14091416

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+
14101434
/*
14111435
* Now create the new index.
14121436
*
@@ -1428,6 +1452,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
14281452
indclass->values,
14291453
opclassOptions,
14301454
indcoloptions->values,
1455+
stattargets,
14311456
reloptionsDatum,
14321457
INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT,
14331458
0,
@@ -1771,72 +1796,6 @@ index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName)
17711796
/* Copy data of pg_statistic from the old index to the new one */
17721797
CopyStatistics(oldIndexId, newIndexId);
17731798

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-
18401799
/* Close relations */
18411800
table_close(pg_class, RowExclusiveLock);
18421801
table_close(pg_index, RowExclusiveLock);

src/backend/catalog/toasting.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
323323
list_make2("chunk_id", "chunk_seq"),
324324
BTREE_AM_OID,
325325
rel->rd_rel->reltablespace,
326-
collationIds, opclassIds, NULL, coloptions, (Datum) 0,
326+
collationIds, opclassIds, NULL, coloptions, NULL, (Datum) 0,
327327
INDEX_CREATE_IS_PRIMARY, 0, true, true, NULL);
328328

329329
table_close(toast_rel, NoLock);

src/backend/commands/indexcmds.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,7 @@ DefineIndex(Oid tableId,
12101210
stmt->oldNumber, indexInfo, indexColNames,
12111211
accessMethodId, tablespaceId,
12121212
collationIds, opclassIds, opclassOptions,
1213-
coloptions, reloptions,
1213+
coloptions, NULL, reloptions,
12141214
flags, constr_flags,
12151215
allowSystemTableMods, !check_rights,
12161216
&createdConstraintId);

src/include/catalog/index.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extern Oid index_create(Relation heapRelation,
8080
const Oid *opclassIds,
8181
const Datum *opclassOptions,
8282
const int16 *coloptions,
83+
const NullableDatum *stattargets,
8384
Datum reloptions,
8485
bits16 flags,
8586
bits16 constr_flags,

src/include/catalog/pg_attribute.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ typedef FormData_pg_attribute *Form_pg_attribute;
218218
*/
219219
typedef struct FormExtraData_pg_attribute
220220
{
221+
NullableDatum attstattarget;
221222
NullableDatum attoptions;
222223
} FormExtraData_pg_attribute;
223224

0 commit comments

Comments
 (0)