Skip to content

Conversation

@gburd
Copy link
Owner

@gburd gburd commented Nov 13, 2025

No description provided.

This commit provides a set of macros that should be used when inserting
or updating tuples before calling CatalogTupleUpdate() or
CatalogTupleInsert().  Historically there have been two methods for
accomplishing this task; Form/GETSTRUCT, and values/nulls/replaces.
This new method provides a more intuitive and less error-prone approach
without changing the fundamentals of the process.  In addition, it is
now possible to retain knowledge of the set of mutated attributes when
working with catalog tuples.  This isn't used in practice (yet), but
could be a way to avoid the overhead of HeapDetermineColumnsInfo() in
heap_update() where (while holding a lock) we re-discover that set by
comparing old/new HeapTuple datums when trying to find what indexed
attributes have new values and prevent HOT updates.

The "Form/GETSTRUCT" model allows for direct access to the tuple data
that is then modified, copied, and then updated via
CatalogTupleUpdate().

Old:
Form_pg_index relform = (Form_pg_index) GETSTRUCT(tuple);
relform->inisclustered = false;
CatalogTupleUpdate(pg_index, &tuple->t_self, tuple);

New:
Bitmapset *updated = NULL;
Form_pg_index relform = (Form_pg_index) GETSTRUCT(tuple);
HeapTupleUpdateField(pg_index, indisclustered, false, indexForm, updated);
CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple, updated, NULL);
bms_free(updated);

The "values/nulls/replaces" model collects the necessary information to
either update or create a heap tuple using heap_modify_tuple() or
heap_form_tuple() or sometimes heap_modify_tuple_by_cols().  While all
those functions remain unchanged now the prefered function for catalog
tuple modification is heap_update_tuple().

Old:
bool    nulls[Natts_pg_type];
bool    replaces[Natts_pg_type];
Datum   values[Natts_pg_type];

values[Anum_pg_type_typtype - 1] = CharGetDatum(typeType);
nulls[Anum_pg_type_typdefaultbin - 1] = true;
replaces[Anum_pg_type_oid - 1] = false;

tup = heap_modify_tuple(tuple, desc, values, nulls, replaces);
CatalogTupleUpdate(pg_type_desc, &tuple->t_self, tuple);

New:
Datum       values[Natts_pg_type] = {0};
bool        nulls[Natts_pg_type] = {false};
Bitmapset  *updated = NULL;

HeapTupleUpdateValue(pg_type, typtype, CharGetDatum(typeType), values, nulls, updated);
HeapTupleUpdateValueNull(pg_type, typdefaultbin, values, nulls, updated);
HeapTupleSetColumnNotUpdated(pg_type, oid, updated);

tup = heap_update_tuple(tuple, desc, values, nulls, updated);
CatalogTupleUpdate(pg_type_desc, &tuple->t_self, tuple, updated, NULL);

In addition CatalogTupleUpdate and CatalogTupleInsert now have an
optional argument for the CatalogIndexState, when not provided it is
created and then released for the caller.

The heap_update_tuple() function is functionally equivalent to
heap_modify_tuple(), but takes a Bitmapset called "updated" rather than
an array of bool generally called "replaces" as a method for indicating
what was modified.  Additionally, this new function tries to balance the
tradeoffs of calling heap_getattr() versus heap_deform_tuple() based
on the ratio of attributes updated and their known runtime complexities.
Both paths are functionally equivalent.

The changes also include initialization of the values/nulls arrays
rather than loops or memset().  Some effort was also given to unify
naming of these variables and their order so as to lower cognitive
overhead.

There is no impact to non-catalog related paths.
Apply all necessary changes to use the new macros for catalog tuples.
This commit finishes the work started in the previous one.  There should
be no behavioural changes resulting from these commits.  This simply
provides a syntatic change with the additional ability to maintain the
set of updated attributes during catalog updates.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants