v1-0003-Nodesupport-add-support-for-custom-default-values.patch
application/octet-stream
Filename: v1-0003-Nodesupport-add-support-for-custom-default-values.patch
Type: application/octet-stream
Part: 4
Patch
Format: format-patch
Series: patch v1-0003
Subject: Nodesupport: add support for custom default values
| File | + | − |
|---|---|---|
| src/backend/nodes/gen_node_support.pl | 56 | 30 |
| src/backend/nodes/outfuncs.c | 2 | 0 |
| src/backend/nodes/readfuncs.c | 2 | 0 |
| src/include/nodes/parsenodes.h | 1 | 1 |
| src/include/nodes/pathnodes.h | 1 | 1 |
| src/include/nodes/primnodes.h | 11 | 11 |
From b53fa22d12dbf7b104284866802923838f97ad2e Mon Sep 17 00:00:00 2001
From: Matthias van de Meent <boekewurm+postgres@gmail.com>
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