From b53fa22d12dbf7b104284866802923838f97ad2e Mon Sep 17 00:00:00 2001 From: Matthias van de Meent Date: Wed, 3 Jan 2024 02:17:19 +0100 Subject: [PATCH v1 3/7] Nodesupport: add support for custom default values Initial testing on typmod values shows that pg_rewrite's ev_action column data shrinks by about 4% with only these changes. --- src/backend/nodes/gen_node_support.pl | 86 +++++++++++++++++---------- src/backend/nodes/outfuncs.c | 2 + src/backend/nodes/readfuncs.c | 2 + src/include/nodes/parsenodes.h | 2 +- src/include/nodes/pathnodes.h | 2 +- src/include/nodes/primnodes.h | 22 +++---- 6 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl index c7091d6bf2..5586368475 100644 --- a/src/backend/nodes/gen_node_support.pl +++ b/src/backend/nodes/gen_node_support.pl @@ -362,6 +362,12 @@ foreach my $infile (@ARGV) { $manual_nodetag_number{$in_struct} = $1; } + elsif ($attr =~ /^default\(([\w\d."'-]+)\)$/) + { + } + elsif ($attr =~ /^default_ref\(([\w\d."'-]+)\)$/) + { + } else { die @@ -436,7 +442,7 @@ foreach my $infile (@ARGV) } # normal struct field elsif ($line =~ - /^\s*(.+)\s*\b(\w+)(\[[\w\s+]+\])?\s*(?:pg_node_attr\(([\w(), ]*)\))?;/ + /^\s*(.+)\s*\b(\w+)(\[[\w\s+]+\])?\s*(?:pg_node_attr\(([\w\d(), ."'-]*)\))?;/ ) { if ($is_node_struct) @@ -468,6 +474,8 @@ foreach my $infile (@ARGV) if ( $attr !~ /^array_size\(\w+\)$/ && $attr !~ /^copy_as\(\w+\)$/ && $attr !~ /^read_as\(\w+\)$/ + && $attr !~ /^default\([\w\d."'-]+\)$/ + && $attr !~ /^default_ref\([\w\d."'-]+\)$/ && !elem $attr, qw(copy_as_scalar equal_as_scalar @@ -494,7 +502,7 @@ foreach my $infile (@ARGV) } # function pointer field elsif ($line =~ - /^\s*([\w\s*]+)\s*\(\*(\w+)\)\s*\((.*)\)\s*(?:pg_node_attr\(([\w(), ]*)\))?;/ + /^\s*([\w\s*]+)\s*\(\*(\w+)\)\s*\((.*)\)\s*(?:pg_node_attr\(([\w\d(), ."'-]*)\))?;/ ) { if ($is_node_struct) @@ -969,6 +977,11 @@ _read${n}(void) my $array_size_field; my $read_as_field; my $read_write_ignore = 0; + # macro suffix ("_DEFAULT" for manual default overrides) and default + # value argument. + my $s = ""; + my $d = ""; + foreach my $a (@a) { if ($a =~ /^array_size\(([\w.]+)\)$/) @@ -987,6 +1000,19 @@ _read${n}(void) { $read_write_ignore = 1; } + elsif ($a =~ /^default\(([\w\d+."'-]+)\)$/) + { + $d = ", $1"; + } + elsif ($a =~ /^default_ref\(([\w\d+."'-]+)\)$/) + { + $d = ", NODE_FIELD($1)"; + } + } + + if (!($d eq "")) + { + $s = "_DEFAULT"; } if ($read_write_ignore) @@ -1007,13 +1033,13 @@ _read${n}(void) # select instructions by field type if ($t eq 'bool') { - print $off "\tWRITE_BOOL_FIELD($f);\n"; - print $rff "\tREAD_BOOL_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_BOOL_FIELD$s($f$d);\n"; + print $rff "\tREAD_BOOL_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'int' && $f =~ 'location$') { - print $off "\tWRITE_LOCATION_FIELD($f);\n"; - print $rff "\tREAD_LOCATION_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_LOCATION_FIELD$s($f$d);\n"; + print $rff "\tREAD_LOCATION_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'int' || $t eq 'int16' @@ -1021,8 +1047,8 @@ _read${n}(void) || $t eq 'AttrNumber' || $t eq 'StrategyNumber') { - print $off "\tWRITE_INT_FIELD($f);\n"; - print $rff "\tREAD_INT_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_INT_FIELD$s($f$d);\n"; + print $rff "\tREAD_INT_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'uint32' || $t eq 'bits32' @@ -1030,44 +1056,44 @@ _read${n}(void) || $t eq 'Index' || $t eq 'SubTransactionId') { - print $off "\tWRITE_UINT_FIELD($f);\n"; - print $rff "\tREAD_UINT_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_UINT_FIELD$s($f$d);\n"; + print $rff "\tREAD_UINT_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'uint64' || $t eq 'AclMode') { - print $off "\tWRITE_UINT64_FIELD($f);\n"; - print $rff "\tREAD_UINT64_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_UINT64_FIELD$s($f$d);\n"; + print $rff "\tREAD_UINT64_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'Oid' || $t eq 'RelFileNumber') { - print $off "\tWRITE_OID_FIELD($f);\n"; - print $rff "\tREAD_OID_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_OID_FIELD$s($f$d);\n"; + print $rff "\tREAD_OID_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'long') { - print $off "\tWRITE_LONG_FIELD($f);\n"; - print $rff "\tREAD_LONG_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_LONG_FIELD$s($f$d);\n"; + print $rff "\tREAD_LONG_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'char') { - print $off "\tWRITE_CHAR_FIELD($f);\n"; - print $rff "\tREAD_CHAR_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_CHAR_FIELD$s($f$d);\n"; + print $rff "\tREAD_CHAR_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'double') { - print $off "\tWRITE_FLOAT_FIELD($f);\n"; - print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_FLOAT_FIELD$s($f$d);\n"; + print $rff "\tREAD_FLOAT_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'Cardinality') { - print $off "\tWRITE_FLOAT_FIELD($f);\n"; - print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_FLOAT_FIELD$s($f$d);\n"; + print $rff "\tREAD_FLOAT_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'Cost') { - print $off "\tWRITE_FLOAT_FIELD($f);\n"; - print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_FLOAT_FIELD$s($f$d);\n"; + print $rff "\tREAD_FLOAT_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'QualCost') { @@ -1078,13 +1104,13 @@ _read${n}(void) } elsif ($t eq 'Selectivity') { - print $off "\tWRITE_FLOAT_FIELD($f);\n"; - print $rff "\tREAD_FLOAT_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_FLOAT_FIELD$s($f$d);\n"; + print $rff "\tREAD_FLOAT_FIELD$s($f$d);\n" unless $no_read; } elsif ($t eq 'char*') { - print $off "\tWRITE_STRING_FIELD($f);\n"; - print $rff "\tREAD_STRING_FIELD($f);\n" unless $no_read; + print $off "\tWRITE_STRING_FIELD($f$d);\n"; + print $rff "\tREAD_STRING_FIELD($f$d);\n" unless $no_read; } elsif ($t eq 'Bitmapset*' || $t eq 'Relids') { @@ -1093,8 +1119,8 @@ _read${n}(void) } elsif (elem $t, @enum_types) { - print $off "\tWRITE_ENUM_FIELD($f, $t);\n"; - print $rff "\tREAD_ENUM_FIELD($f, $t);\n" unless $no_read; + print $off "\tWRITE_ENUM_FIELD$s($f, $t$d);\n"; + print $rff "\tREAD_ENUM_FIELD$s($f, $t$d);\n" unless $no_read; } # arrays of scalar types elsif ($t =~ /^(\w+)(\*|\[\w+\])$/ and elem $1, @scalar_types) diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 29f4e43581..73f1298dee 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -193,6 +193,8 @@ static void outDouble(StringInfo str, double d); #define WRITE_BOOL_ARRAY(fldname, len) \ (node->fldname == NULL ? (0) : WRITE_BOOL_ARRAY_DIRECT(fldname, len)) +#define NODE_FIELD(fldname) (node->fldname) + #define booltostr(x) ((x) ? "true" : "false") diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 74a2204389..dd1e505bd7 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -256,6 +256,8 @@ #define READ_BOOL_ARRAY(fldname, len) \ READ_BOOL_ARRAY_DEFAULT(fldname, len, NULL) +#define NODE_FIELD(fldname) (local_node->fldname) + /* Routine exit */ #define READ_DONE() \ return local_node diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index e494309da8..b9f122b46c 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1608,7 +1608,7 @@ typedef struct CTECycleClause int location; /* These fields are set during parse analysis: */ Oid cycle_mark_type; /* common type of _value and _default */ - int cycle_mark_typmod; + int cycle_mark_typmod pg_node_attr(default(-1)); Oid cycle_mark_collation; Oid cycle_mark_neop; /* <> operator for type */ } CTECycleClause; diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index ed85dc7414..e688fc2b79 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -3379,7 +3379,7 @@ typedef struct AggTransInfo Oid aggtranstype; /* Additional data about transtype */ - int32 aggtranstypmod; + int32 aggtranstypmod pg_node_attr(default(-1)); int transtypeLen; bool transtypeByVal; diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index bb930afb52..c9b30b1b0d 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -248,7 +248,7 @@ typedef struct Var /* pg_type OID for the type of this var */ Oid vartype pg_node_attr(query_jumble_ignore); /* pg_attribute typmod value */ - int32 vartypmod pg_node_attr(query_jumble_ignore); + int32 vartypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation, or InvalidOid if none */ Oid varcollid pg_node_attr(query_jumble_ignore); @@ -297,7 +297,7 @@ typedef struct Const /* pg_type OID of the constant's datatype */ Oid consttype; /* typmod value, if any */ - int32 consttypmod pg_node_attr(query_jumble_ignore); + int32 consttypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation, or InvalidOid if none */ Oid constcollid pg_node_attr(query_jumble_ignore); /* typlen of the constant's datatype */ @@ -363,7 +363,7 @@ typedef struct Param int paramid; /* numeric ID for parameter */ Oid paramtype; /* pg_type OID of parameter's datatype */ /* typmod value, if known */ - int32 paramtypmod pg_node_attr(query_jumble_ignore); + int32 paramtypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation, or InvalidOid if none */ Oid paramcollid pg_node_attr(query_jumble_ignore); /* token location, or -1 if unknown */ @@ -621,7 +621,7 @@ typedef struct SubscriptingRef /* type of the SubscriptingRef's result */ Oid refrestype pg_node_attr(query_jumble_ignore); /* typmod of the result */ - int32 reftypmod pg_node_attr(query_jumble_ignore); + int32 reftypmod pg_node_attr(query_jumble_ignore, default(-1)); /* collation of result, or InvalidOid if none */ Oid refcollid pg_node_attr(query_jumble_ignore); /* expressions that evaluate to upper container indexes */ @@ -1065,7 +1065,7 @@ typedef struct FieldSelect /* type of the field (result type of this node) */ Oid resulttype pg_node_attr(query_jumble_ignore); /* output typmod (usually -1) */ - int32 resulttypmod pg_node_attr(query_jumble_ignore); + int32 resulttypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation of the field */ Oid resultcollid pg_node_attr(query_jumble_ignore); } FieldSelect; @@ -1119,7 +1119,7 @@ typedef struct RelabelType Expr *arg; /* input expression */ Oid resulttype; /* output type of coercion expression */ /* output typmod (usually -1) */ - int32 resulttypmod pg_node_attr(query_jumble_ignore); + int32 resulttypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation, or InvalidOid if none */ Oid resultcollid pg_node_attr(query_jumble_ignore); /* how to display this node */ @@ -1169,7 +1169,7 @@ typedef struct ArrayCoerceExpr Expr *elemexpr; /* expression representing per-element work */ Oid resulttype; /* output type of coercion (an array type) */ /* output typmod (also element typmod) */ - int32 resulttypmod pg_node_attr(query_jumble_ignore); + int32 resulttypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation, or InvalidOid if none */ Oid resultcollid pg_node_attr(query_jumble_ignore); /* how to display this node */ @@ -1495,7 +1495,7 @@ typedef struct SQLValueFunction * include this Oid in the query jumbling. */ Oid type pg_node_attr(query_jumble_ignore); - int32 typmod; + int32 typmod pg_node_attr(default(-1)); int location; /* token location, or -1 if unknown */ } SQLValueFunction; @@ -1547,7 +1547,7 @@ typedef struct XmlExpr bool indent; /* target type/typmod for XMLSERIALIZE */ Oid type pg_node_attr(query_jumble_ignore); - int32 typmod pg_node_attr(query_jumble_ignore); + int32 typmod pg_node_attr(query_jumble_ignore, default(-1)); /* token location, or -1 if unknown */ int location; } XmlExpr; @@ -1597,7 +1597,7 @@ typedef struct JsonReturning NodeTag type; JsonFormat *format; /* output JSON format */ Oid typid; /* target type Oid */ - int32 typmod; /* target type modifier */ + int32 typmod pg_node_attr(default(-1)); /* target type modifier */ } JsonReturning; /* @@ -1760,7 +1760,7 @@ typedef struct CoerceToDomain Expr *arg; /* input expression */ Oid resulttype; /* domain type ID (result type) */ /* output typmod (currently always -1) */ - int32 resulttypmod pg_node_attr(query_jumble_ignore); + int32 resulttypmod pg_node_attr(query_jumble_ignore, default(-1)); /* OID of collation, or InvalidOid if none */ Oid resultcollid pg_node_attr(query_jumble_ignore); /* how to display this node */ -- 2.40.1