diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 5e773740f4..de982c2c52 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -684,10 +684,11 @@ CheckAttributeType(const char *attname, * Construct and insert a set of tuples in pg_attribute. * * Caller has already opened and locked pg_attribute. tupdesc contains the - * attributes to insert. attcacheoff is always initialized to -1. attoptions - * supplies the values for the attoptions fields and must contain the same - * number of elements as tupdesc or be NULL. The other variable-length fields - * of pg_attribute are always initialized to null values. + * attributes to insert. attcacheoff is always initialized to -1. + * tupdesc_extra supplies the values for certain variable-length/nullable + * pg_attribute fields and must contain the same number of elements as tupdesc + * or be NULL. The other variable-length fields of pg_attribute are always + * initialized to null values. * * indstate is the index state for CatalogTupleInsertWithInfo. It can be * passed as NULL, in which case we'll fetch the necessary info. (Don't do @@ -701,7 +702,7 @@ void InsertPgAttributeTuples(Relation pg_attribute_rel, TupleDesc tupdesc, Oid new_rel_oid, - const Datum *attoptions, + const FormExtraData_pg_attribute tupdesc_extra[], CatalogIndexState indstate) { TupleTableSlot **slot; @@ -723,6 +724,7 @@ InsertPgAttributeTuples(Relation pg_attribute_rel, while (natts < tupdesc->natts) { Form_pg_attribute attrs = TupleDescAttr(tupdesc, natts); + const FormExtraData_pg_attribute *attrs_extra = tupdesc_extra ? &tupdesc_extra[natts] : NULL; ExecClearTuple(slot[slotCount]); @@ -754,10 +756,15 @@ InsertPgAttributeTuples(Relation pg_attribute_rel, slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal); slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int16GetDatum(attrs->attinhcount); slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation); - if (attoptions && attoptions[natts] != (Datum) 0) - slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attoptions[natts]; + if (attrs_extra) + { + 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_attoptions - 1] = true; + } /* * The remaining fields are not set for new columns. diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index e6140853c0..7e428f3eb7 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -512,6 +512,20 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts) Relation pg_attribute; CatalogIndexState indstate; TupleDesc indexTupDesc; + FormExtraData_pg_attribute *attrs_extra = NULL; + + if (attopts) + { + attrs_extra = palloc0_array(FormExtraData_pg_attribute, indexRelation->rd_att->natts); + + for (int i = 0; i < indexRelation->rd_att->natts; i++) + { + if (attopts[i]) + attrs_extra[i].attoptions.value = attopts[i]; + else + attrs_extra[i].attoptions.isnull = true; + } + } /* * open the attribute relation and its indexes @@ -525,7 +539,7 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts) */ indexTupDesc = RelationGetDescr(indexRelation); - InsertPgAttributeTuples(pg_attribute, indexTupDesc, InvalidOid, attopts, indstate); + InsertPgAttributeTuples(pg_attribute, indexTupDesc, InvalidOid, attrs_extra, indstate); CatalogCloseIndexes(indstate); diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 1d7f8380d9..21e31f9c97 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -98,7 +98,7 @@ extern List *heap_truncate_find_FKs(List *relationIds); extern void InsertPgAttributeTuples(Relation pg_attribute_rel, TupleDesc tupdesc, Oid new_rel_oid, - const Datum *attoptions, + const FormExtraData_pg_attribute tupdesc_extra[], CatalogIndexState indstate); extern void InsertPgClassTuple(Relation pg_class_desc, diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index 9f2706c4e8..1cc7a848f0 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -208,6 +208,19 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75, */ typedef FormData_pg_attribute *Form_pg_attribute; +/* + * FormExtraData_pg_attribute contains (some of) the fields that are not in + * FormData_pg_attribute because they are excluded by CATALOG_VARLEN. It is + * meant to be used by DDL code so that the combination of + * FormData_pg_attribute (often via tuple descriptor) and + * FormExtraData_pg_attribute can be used to pass around all the information + * about an attribute. Fields can be included here as needed. + */ +typedef struct FormExtraData_pg_attribute +{ + NullableDatum attoptions; +} FormExtraData_pg_attribute; + DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index, 2658, AttributeRelidNameIndexId, pg_attribute, btree(attrelid oid_ops, attname name_ops)); DECLARE_UNIQUE_INDEX_PKEY(pg_attribute_relid_attnum_index, 2659, AttributeRelidNumIndexId, pg_attribute, btree(attrelid oid_ops, attnum int2_ops)); diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index aa7a25b8f8..9ba7a9a56c 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -850,6 +850,7 @@ FormData_pg_ts_parser FormData_pg_ts_template FormData_pg_type FormData_pg_user_mapping +FormExtraData_pg_attribute Form_pg_aggregate Form_pg_am Form_pg_amop