From 8a5509dcefb0f6cf975d2bd8091f7712f43c5512 Mon Sep 17 00:00:00 2001 From: John Naylor Date: Mon, 1 Aug 2022 17:42:14 +0700 Subject: [PATCH v3 2/2] Generate pg_cast function to deform tuples into structs This catalog presents no challenges for alignment padding, but has few call sites where deforming is done, so is an easy PoC. In objectaddress.c, use the generated Deform_pg_cast_tuple() to copy values to a passed struct. For tuples stored in syscaches, continue to do a simple cast. A future commit will store the struct in the caches rather than the tuple, at which point we will need to teach syscache misses to use the appropriate deforming function as well. --- src/backend/catalog/Makefile | 1 + src/backend/catalog/genbki.pl | 56 ++++++++++++++++++++++++++++- src/backend/catalog/objectaddress.c | 20 +++++------ src/include/catalog/pg_cast.h | 1 + 4 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index 89a0221ec9..fe2f8ccfbf 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -17,6 +17,7 @@ OBJS = \ aclchk.o \ catalog.o \ dependency.o \ + deform_catalog_tuple.o \ heap.o \ index.o \ indexing.o \ diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index 17b2c5e3f3..6afd2b8f25 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -405,6 +405,10 @@ my %lookup_kind = ( pg_type => \%typeoids, encoding => \%encids); +# Map type to DatumGet* macro +my %datumget = ( + oid => 'DatumGetObjectId', + char => 'DatumGetChar'); # Open temp files my $tmpext = ".tmp$$"; @@ -420,6 +424,9 @@ open my $fk_info, '>', $fk_info_file . $tmpext my $constraints_file = $output_path . 'system_constraints.sql'; open my $constraints, '>', $constraints_file . $tmpext or die "can't open $constraints_file$tmpext: $!"; +my $deform_file = $output_path . 'deform_catalog_tuple.c'; +open my $deform, '>', $deform_file . $tmpext + or die "can't open $deform_file$tmpext: $!"; # Generate postgres.bki and pg_*_d.h headers. @@ -430,6 +437,32 @@ print $bki "# PostgreSQL $major_version\n"; my %schemapg_entries; my @tables_needing_macros; +# Opening boilerplate for deform_catalog_tuple.c +printf $deform <{relation_oid_macro}, $catalog->{relation_oid} @@ -538,6 +583,11 @@ EOM # Emit Anum_* constants printf $def "#define Anum_%s_%s %s\n", $catname, $attname, $attnum; + + if ($catname eq 'pg_cast') { # WIP + printf $deform "\t%s_struct->%s = %s(values[Anum_%s_%s - 1]);\n", + $catname, $attname, $datumget{$atttype}, $catname, $attname; + } } print $bki "\n )\n"; @@ -673,7 +723,9 @@ EOM print $bki "close $catname\n"; printf $def "\n#endif\t\t\t\t\t\t\t/* %s_D_H */\n", uc $catname; - + if ($catname eq 'pg_cast') { # WIP + print $deform "}\n\n"; + } # Close and rename definition header close $def; Catalog::RenameTempFile($def_file, $tmpext); @@ -807,12 +859,14 @@ close $bki; close $schemapg; close $fk_info; close $constraints; +close $deform; # Finally, rename the completed files into place. Catalog::RenameTempFile($bkifile, $tmpext); Catalog::RenameTempFile($schemafile, $tmpext); Catalog::RenameTempFile($fk_info_file, $tmpext); Catalog::RenameTempFile($constraints_file, $tmpext); +Catalog::RenameTempFile($deform_file, $tmpext); exit($num_errors != 0 ? 1 : 0); diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 4991a76c41..de23836037 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -3003,7 +3003,7 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) ScanKeyData skey[1]; SysScanDesc rcscan; HeapTuple tup; - Form_pg_cast castForm; + FormData_pg_cast castForm; castDesc = table_open(CastRelationId, AccessShareLock); @@ -3028,11 +3028,11 @@ getObjectDescription(const ObjectAddress *object, bool missing_ok) break; } - castForm = GETSTRUCT(pg_cast, tup); + Deform_pg_cast_tuple(&castForm, tup, RelationGetDescr(castDesc)); appendStringInfo(&buffer, _("cast from %s to %s"), - format_type_be(castForm->castsource), - format_type_be(castForm->casttarget)); + format_type_be(castForm.castsource), + format_type_be(castForm.casttarget)); systable_endscan(rcscan); table_close(castDesc, AccessShareLock); @@ -4853,7 +4853,7 @@ getObjectIdentityParts(const ObjectAddress *object, { Relation castRel; HeapTuple tup; - Form_pg_cast castForm; + FormData_pg_cast castForm; castRel = table_open(CastRelationId, AccessShareLock); @@ -4870,16 +4870,16 @@ getObjectIdentityParts(const ObjectAddress *object, break; } - castForm = GETSTRUCT(pg_cast, tup); + Deform_pg_cast_tuple(&castForm, tup, RelationGetDescr(castRel)); appendStringInfo(&buffer, "(%s AS %s)", - format_type_be_qualified(castForm->castsource), - format_type_be_qualified(castForm->casttarget)); + format_type_be_qualified(castForm.castsource), + format_type_be_qualified(castForm.casttarget)); if (objname) { - *objname = list_make1(format_type_be_qualified(castForm->castsource)); - *objargs = list_make1(format_type_be_qualified(castForm->casttarget)); + *objname = list_make1(format_type_be_qualified(castForm.castsource)); + *objargs = list_make1(format_type_be_qualified(castForm.casttarget)); } table_close(castRel, AccessShareLock); diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index 3c15df0053..fde557477a 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -91,6 +91,7 @@ typedef enum CoercionMethod #endif /* EXPOSE_TO_CLIENT_CODE */ +extern void Deform_pg_cast_tuple(Form_pg_cast pg_cast_struct, HeapTuple pg_cast_tuple, TupleDesc pg_cast_desc); extern ObjectAddress CastCreate(Oid sourcetypeid, Oid targettypeid, -- 2.36.1