Remove artificial restrictions on which node types have out/read funcs.

The initial version of gen_node_support.pl manually excluded most
utility statement node types from having out/read support, and
also some raw-parse-tree-only node types.  That was mostly to keep
the output comparable to the old hand-maintained code.  We'd like
to have out/read support for utility statements, for debugging
purposes and so that they can be included in new-style SQL functions;
so it's time to lift that restriction.

Most if not all of the previously-excluded raw-parse-tree-only node
types can appear in expression subtrees of utility statements, so
they have to be handled too.

We don't quite have full read support yet; certain custom_read_write
node types need to have their handwritten read functions implemented
before that will work.

Doing this allows us to drop the previous hack in _outQuery to not
dump the utilityStmt field in most cases, which means we no longer
need manually-maintained out/read functions for Query, so get rid
of those in favor of auto-generating them.

Fix a couple of omissions in gen_node_support.pl that are exposed
through having to handle more node types.

catversion bump forced because somebody was sloppy about the field
order in the manually-maintained Query out/read functions.
(Committers should note that almost all changes in parsenodes.h
are now grounds for a catversion bump.)
This commit is contained in:
Tom Lane 2022-07-13 11:48:17 -04:00
parent 9c727360bc
commit ff33a8c887
5 changed files with 19 additions and 159 deletions

View File

@ -166,23 +166,6 @@ push @scalar_types, qw(EquivalenceClass* EquivalenceMember*);
# currently not required.
push @scalar_types, qw(QualCost);
# XXX various things we are not publishing right now to stay level
# with the manual system
push @no_read_write,
qw(AccessPriv AlterTableCmd CreateOpClassItem FunctionParameter InferClause ObjectWithArgs OnConflictClause PartitionCmd RoleSpec VacuumRelation);
push @no_read, qw(A_ArrayExpr A_Indices A_Indirection AlterStatsStmt
CollateClause ColumnDef ColumnRef CreateForeignTableStmt CreateStatsStmt
CreateStmt FuncCall ImportForeignSchemaStmt IndexElem IndexStmt
JsonAggConstructor JsonArgument JsonArrayAgg JsonArrayConstructor
JsonArrayQueryConstructor JsonCommon JsonFuncExpr JsonKeyValue
JsonObjectAgg JsonObjectConstructor JsonOutput JsonParseExpr JsonScalarExpr
JsonSerializeExpr JsonTable JsonTableColumn JsonTablePlan LockingClause
MultiAssignRef PLAssignStmt ParamRef PartitionElem PartitionSpec
PlaceHolderVar PublicationObjSpec PublicationTable RangeFunction
RangeSubselect RangeTableFunc RangeTableFuncCol RangeTableSample RawStmt
ResTarget ReturnStmt SelectStmt SortBy StatsElem TableLikeClause
TriggerTransition TypeCast TypeName WindowDef WithClause XmlSerialize);
## check that we have the expected number of files on the command line
die "wrong number of input files, expected @all_input_files\n"
@ -795,14 +778,6 @@ foreach my $n (@node_types)
next if elem $n, @nodetag_only;
next if elem $n, @no_read_write;
# XXX For now, skip all "Stmt"s except that ones that were there before.
if ($n =~ /Stmt$/)
{
my @keep =
qw(AlterStatsStmt CreateForeignTableStmt CreateStatsStmt CreateStmt DeclareCursorStmt ImportForeignSchemaStmt IndexStmt NotifyStmt PlannedStmt PLAssignStmt RawStmt ReturnStmt SelectStmt SetOperationStmt);
next unless elem $n, @keep;
}
my $no_read = (elem $n, @no_read);
# output format starts with upper case node type name
@ -827,13 +802,20 @@ _out${n}(StringInfo str, const $n *node)
";
print $rff "
if (!$no_read)
{
my $macro =
(@{ $node_type_info{$n}->{fields} } > 0)
? 'READ_LOCALS'
: 'READ_LOCALS_NO_FIELDS';
print $rff "
static $n *
_read${n}(void)
{
\tREAD_LOCALS($n);
\t$macro($n);
" unless $no_read;
";
}
# print instructions for each field
foreach my $f (@{ $node_type_info{$n}->{fields} })
@ -883,6 +865,7 @@ _read${n}(void)
print $rff "\tREAD_LOCATION_FIELD($f);\n" unless $no_read;
}
elsif ($t eq 'int'
|| $t eq 'int16'
|| $t eq 'int32'
|| $t eq 'AttrNumber'
|| $t eq 'StrategyNumber')

View File

@ -415,79 +415,6 @@ _outExtensibleNode(StringInfo str, const ExtensibleNode *node)
methods->nodeOut(str, node);
}
static void
_outQuery(StringInfo str, const Query *node)
{
WRITE_NODE_TYPE("QUERY");
WRITE_ENUM_FIELD(commandType, CmdType);
WRITE_ENUM_FIELD(querySource, QuerySource);
/* we intentionally do not print the queryId field */
WRITE_BOOL_FIELD(canSetTag);
/*
* Hack to work around missing outfuncs routines for a lot of the
* utility-statement node types. (The only one we actually *need* for
* rules support is NotifyStmt.) Someday we ought to support 'em all, but
* for the meantime do this to avoid getting lots of warnings when running
* with debug_print_parse on.
*/
if (node->utilityStmt)
{
switch (nodeTag(node->utilityStmt))
{
case T_CreateStmt:
case T_IndexStmt:
case T_NotifyStmt:
case T_DeclareCursorStmt:
WRITE_NODE_FIELD(utilityStmt);
break;
default:
appendStringInfoString(str, " :utilityStmt ?");
break;
}
}
else
appendStringInfoString(str, " :utilityStmt <>");
WRITE_INT_FIELD(resultRelation);
WRITE_BOOL_FIELD(hasAggs);
WRITE_BOOL_FIELD(hasWindowFuncs);
WRITE_BOOL_FIELD(hasTargetSRFs);
WRITE_BOOL_FIELD(hasSubLinks);
WRITE_BOOL_FIELD(hasDistinctOn);
WRITE_BOOL_FIELD(hasRecursive);
WRITE_BOOL_FIELD(hasModifyingCTE);
WRITE_BOOL_FIELD(hasForUpdate);
WRITE_BOOL_FIELD(hasRowSecurity);
WRITE_BOOL_FIELD(isReturn);
WRITE_NODE_FIELD(cteList);
WRITE_NODE_FIELD(rtable);
WRITE_NODE_FIELD(jointree);
WRITE_NODE_FIELD(targetList);
WRITE_ENUM_FIELD(override, OverridingKind);
WRITE_NODE_FIELD(onConflict);
WRITE_NODE_FIELD(returningList);
WRITE_NODE_FIELD(groupClause);
WRITE_BOOL_FIELD(groupDistinct);
WRITE_NODE_FIELD(groupingSets);
WRITE_NODE_FIELD(havingQual);
WRITE_NODE_FIELD(windowClause);
WRITE_NODE_FIELD(distinctClause);
WRITE_NODE_FIELD(sortClause);
WRITE_NODE_FIELD(limitOffset);
WRITE_NODE_FIELD(limitCount);
WRITE_ENUM_FIELD(limitOption, LimitOption);
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(setOperations);
WRITE_NODE_FIELD(constraintDeps);
WRITE_NODE_FIELD(withCheckOptions);
WRITE_NODE_FIELD(mergeActionList);
WRITE_BOOL_FIELD(mergeUseOuterJoin);
WRITE_LOCATION_FIELD(stmt_location);
WRITE_INT_FIELD(stmt_len);
}
static void
_outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
{

View File

@ -240,56 +240,6 @@ readBitmapset(void)
* special_read_write attribute
*/
static Query *
_readQuery(void)
{
READ_LOCALS(Query);
READ_ENUM_FIELD(commandType, CmdType);
READ_ENUM_FIELD(querySource, QuerySource);
local_node->queryId = UINT64CONST(0); /* not saved in output format */
READ_BOOL_FIELD(canSetTag);
READ_NODE_FIELD(utilityStmt);
READ_INT_FIELD(resultRelation);
READ_BOOL_FIELD(hasAggs);
READ_BOOL_FIELD(hasWindowFuncs);
READ_BOOL_FIELD(hasTargetSRFs);
READ_BOOL_FIELD(hasSubLinks);
READ_BOOL_FIELD(hasDistinctOn);
READ_BOOL_FIELD(hasRecursive);
READ_BOOL_FIELD(hasModifyingCTE);
READ_BOOL_FIELD(hasForUpdate);
READ_BOOL_FIELD(hasRowSecurity);
READ_BOOL_FIELD(isReturn);
READ_NODE_FIELD(cteList);
READ_NODE_FIELD(rtable);
READ_NODE_FIELD(jointree);
READ_NODE_FIELD(targetList);
READ_ENUM_FIELD(override, OverridingKind);
READ_NODE_FIELD(onConflict);
READ_NODE_FIELD(returningList);
READ_NODE_FIELD(groupClause);
READ_BOOL_FIELD(groupDistinct);
READ_NODE_FIELD(groupingSets);
READ_NODE_FIELD(havingQual);
READ_NODE_FIELD(windowClause);
READ_NODE_FIELD(distinctClause);
READ_NODE_FIELD(sortClause);
READ_NODE_FIELD(limitOffset);
READ_NODE_FIELD(limitCount);
READ_ENUM_FIELD(limitOption, LimitOption);
READ_NODE_FIELD(rowMarks);
READ_NODE_FIELD(setOperations);
READ_NODE_FIELD(constraintDeps);
READ_NODE_FIELD(withCheckOptions);
READ_NODE_FIELD(mergeActionList);
READ_BOOL_FIELD(mergeUseOuterJoin);
READ_LOCATION_FIELD(stmt_location);
READ_INT_FIELD(stmt_len);
READ_DONE();
}
static Const *
_readConst(void)
{

View File

@ -32,6 +32,10 @@
* include/catalog is the most common kind of initdb-forcing change.
* But it could be used to protect any kind of incompatible change in
* database contents or layout, such as altering tuple headers.
* Another common reason for a catversion update is a change in parsetree
* external representation, since serialized parsetrees appear in stored
* rules and new-style SQL functions. Almost any change in primnodes.h or
* parsenodes.h will warrant a catversion update.
*
*
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
@ -53,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202207091
#define CATALOG_VERSION_NO 202207131
#endif

View File

@ -117,8 +117,6 @@ typedef uint32 AclMode; /* a bitmask of privilege bits */
*/
typedef struct Query
{
pg_node_attr(custom_read_write)
NodeTag type;
CmdType commandType; /* select|insert|update|delete|merge|utility */
@ -126,10 +124,10 @@ typedef struct Query
QuerySource querySource; /* where did I come from? */
/*
* query identifier (can be set by plugins); ignored for equal, might not
* be set
* query identifier (can be set by plugins); ignored for equal, as it
* might not be set; also not stored
*/
uint64 queryId pg_node_attr(equal_ignore, read_as(0));
uint64 queryId pg_node_attr(equal_ignore, read_write_ignore, read_as(0));
bool canSetTag; /* do I set the command result tag? */
@ -409,8 +407,6 @@ typedef struct FuncCall
*/
typedef struct A_Star
{
pg_node_attr(no_read)
NodeTag type;
} A_Star;