Remove artificial restrictions on which node types have out/read funcs.
authorTom Lane <[email protected]>
Wed, 13 Jul 2022 15:48:17 +0000 (11:48 -0400)
committerTom Lane <[email protected]>
Wed, 13 Jul 2022 15:48:17 +0000 (11:48 -0400)
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.)

src/backend/nodes/gen_node_support.pl
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/include/catalog/catversion.h
src/include/nodes/parsenodes.h

index 7694e04d0a2f3d7a3804246edb8aa7515327b53f..96af17516aa7701f776a66402d15a57d058b8bc7 100644 (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')
index 9e43fec86d4484f2b179e28a097e2d23b1bca8e6..2b85f97f3982a851e3d4d224a88269a3f12416ee 100644 (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)
 {
index 1421686938f86090f6502c96eb470462bc436079..a2391280bea551a048cfee9fbca9407a2161209d 100644 (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)
 {
index 5eb08c258aedc1cb9f27f9ba79322259154b2491..02ca4aec8c96dc1367bf27d67c33b4fa22c24187 100644 (file)
  * 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
index 3605cea4c7215b8f43e1b9ec7e4485b76eae4541..b0c9c5f2ef67d6d5505ca63c74b9bdd63c527371 100644 (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;