Skip to content

Commit d939cb2

Browse files
committed
Generalize handling of nullable pg_attribute columns in DDL
DDL code uses tuple descriptors to pass around pg_attribute values during table and index creation. But tuple descriptors don't include the variable-length/nullable columns of pg_attribute, so they have to be handled separately. Right now, the attoptions field is handled in a one-off way with a separate argument passed to InsertPgAttributeTuples(). The other affected fields of pg_attribute are right now not needed at relation creation time. The goal of this patch is to generalize this to allow handling additional variable-length/nullable columns of pg_attribute in a similar manner. For that, create a new struct FormExtraData_pg_attribute, which is to be passed around in parallel to the tuple descriptor and optionally supplies the additional columns. Right now, this struct only contains one field for attoptions, so no functionality is actually changed by this. 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 012460e commit d939cb2

File tree

5 files changed

+44
-9
lines changed

5 files changed

+44
-9
lines changed

src/backend/catalog/heap.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -684,10 +684,11 @@ CheckAttributeType(const char *attname,
684684
* Construct and insert a set of tuples in pg_attribute.
685685
*
686686
* Caller has already opened and locked pg_attribute. tupdesc contains the
687-
* attributes to insert. attcacheoff is always initialized to -1. attoptions
688-
* supplies the values for the attoptions fields and must contain the same
689-
* number of elements as tupdesc or be NULL. The other variable-length fields
690-
* of pg_attribute are always initialized to null values.
687+
* attributes to insert. attcacheoff is always initialized to -1.
688+
* tupdesc_extra supplies the values for certain variable-length/nullable
689+
* pg_attribute fields and must contain the same number of elements as tupdesc
690+
* or be NULL. The other variable-length fields of pg_attribute are always
691+
* initialized to null values.
691692
*
692693
* indstate is the index state for CatalogTupleInsertWithInfo. It can be
693694
* passed as NULL, in which case we'll fetch the necessary info. (Don't do
@@ -701,7 +702,7 @@ void
701702
InsertPgAttributeTuples(Relation pg_attribute_rel,
702703
TupleDesc tupdesc,
703704
Oid new_rel_oid,
704-
const Datum *attoptions,
705+
const FormExtraData_pg_attribute tupdesc_extra[],
705706
CatalogIndexState indstate)
706707
{
707708
TupleTableSlot **slot;
@@ -723,6 +724,7 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
723724
while (natts < tupdesc->natts)
724725
{
725726
Form_pg_attribute attrs = TupleDescAttr(tupdesc, natts);
727+
const FormExtraData_pg_attribute *attrs_extra = tupdesc_extra ? &tupdesc_extra[natts] : NULL;
726728

727729
ExecClearTuple(slot[slotCount]);
728730

@@ -754,10 +756,15 @@ InsertPgAttributeTuples(Relation pg_attribute_rel,
754756
slot[slotCount]->tts_values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(attrs->attislocal);
755757
slot[slotCount]->tts_values[Anum_pg_attribute_attinhcount - 1] = Int16GetDatum(attrs->attinhcount);
756758
slot[slotCount]->tts_values[Anum_pg_attribute_attcollation - 1] = ObjectIdGetDatum(attrs->attcollation);
757-
if (attoptions && attoptions[natts] != (Datum) 0)
758-
slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attoptions[natts];
759+
if (attrs_extra)
760+
{
761+
slot[slotCount]->tts_values[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.value;
762+
slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = attrs_extra->attoptions.isnull;
763+
}
759764
else
765+
{
760766
slot[slotCount]->tts_isnull[Anum_pg_attribute_attoptions - 1] = true;
767+
}
761768

762769
/*
763770
* The remaining fields are not set for new columns.

src/backend/catalog/index.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,20 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
512512
Relation pg_attribute;
513513
CatalogIndexState indstate;
514514
TupleDesc indexTupDesc;
515+
FormExtraData_pg_attribute *attrs_extra = NULL;
516+
517+
if (attopts)
518+
{
519+
attrs_extra = palloc0_array(FormExtraData_pg_attribute, indexRelation->rd_att->natts);
520+
521+
for (int i = 0; i < indexRelation->rd_att->natts; i++)
522+
{
523+
if (attopts[i])
524+
attrs_extra[i].attoptions.value = attopts[i];
525+
else
526+
attrs_extra[i].attoptions.isnull = true;
527+
}
528+
}
515529

516530
/*
517531
* open the attribute relation and its indexes
@@ -525,7 +539,7 @@ AppendAttributeTuples(Relation indexRelation, const Datum *attopts)
525539
*/
526540
indexTupDesc = RelationGetDescr(indexRelation);
527541

528-
InsertPgAttributeTuples(pg_attribute, indexTupDesc, InvalidOid, attopts, indstate);
542+
InsertPgAttributeTuples(pg_attribute, indexTupDesc, InvalidOid, attrs_extra, indstate);
529543

530544
CatalogCloseIndexes(indstate);
531545

src/include/catalog/heap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ extern List *heap_truncate_find_FKs(List *relationIds);
9898
extern void InsertPgAttributeTuples(Relation pg_attribute_rel,
9999
TupleDesc tupdesc,
100100
Oid new_rel_oid,
101-
const Datum *attoptions,
101+
const FormExtraData_pg_attribute tupdesc_extra[],
102102
CatalogIndexState indstate);
103103

104104
extern void InsertPgClassTuple(Relation pg_class_desc,

src/include/catalog/pg_attribute.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,19 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,
208208
*/
209209
typedef FormData_pg_attribute *Form_pg_attribute;
210210

211+
/*
212+
* FormExtraData_pg_attribute contains (some of) the fields that are not in
213+
* FormData_pg_attribute because they are excluded by CATALOG_VARLEN. It is
214+
* meant to be used by DDL code so that the combination of
215+
* FormData_pg_attribute (often via tuple descriptor) and
216+
* FormExtraData_pg_attribute can be used to pass around all the information
217+
* about an attribute. Fields can be included here as needed.
218+
*/
219+
typedef struct FormExtraData_pg_attribute
220+
{
221+
NullableDatum attoptions;
222+
} FormExtraData_pg_attribute;
223+
211224
DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index, 2658, AttributeRelidNameIndexId, pg_attribute, btree(attrelid oid_ops, attname name_ops));
212225
DECLARE_UNIQUE_INDEX_PKEY(pg_attribute_relid_attnum_index, 2659, AttributeRelidNumIndexId, pg_attribute, btree(attrelid oid_ops, attnum int2_ops));
213226

src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ FormData_pg_ts_parser
850850
FormData_pg_ts_template
851851
FormData_pg_type
852852
FormData_pg_user_mapping
853+
FormExtraData_pg_attribute
853854
Form_pg_aggregate
854855
Form_pg_am
855856
Form_pg_amop

0 commit comments

Comments
 (0)