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,
* ----------------------------------------------------------------
*/
static void
-AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
+AppendAttributeTuples(Relation indexRelation, const Datum *attopts, const NullableDatum *stattargets)
{
Relation pg_attribute;
CatalogIndexState indstate;
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;
}
}
const Oid *opclassIds,
const Datum *opclassOptions,
const int16 *coloptions,
+ const NullableDatum *stattargets,
Datum reloptions,
bits16 flags,
bits16 constr_flags,
/*
* append ATTRIBUTE tuples for the index
*/
- AppendAttributeTuples(indexRelation, opclassOptions);
+ AppendAttributeTuples(indexRelation, opclassOptions, stattargets);
/* ----------------
* update pg_index
Datum *opclassOptions;
oidvector *indclass;
int2vector *indcoloptions;
+ NullableDatum *stattargets;
bool isnull;
List *indexColNames = NIL;
List *indexExprs = NIL;
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.
*
indclass->values,
opclassOptions,
indcoloptions->values,
+ stattargets,
reloptionsDatum,
INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT,
0,
/* 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);