Invent nodetag_only attribute for Nodes.
authorTom Lane <[email protected]>
Tue, 12 Jul 2022 14:46:58 +0000 (10:46 -0400)
committerTom Lane <[email protected]>
Tue, 12 Jul 2022 14:46:58 +0000 (10:46 -0400)
This allows explaining gen_node_support.pl's handling of execnodes.h
and some other input files as being a shortcut for explicit marking
of all their node declarations as pg_node_attr(nodetag_only).
I foresee that someday we might need to be more fine-grained about
that, and this change provides the infrastructure needed to do so.
For now, it just allows removal of the script's klugy special case
for CallContext and InlineCodeBlock.

Discussion: https://postgr.es/m/75063.1657410615@sss.pgh.pa.us

src/backend/nodes/gen_node_support.pl
src/include/nodes/nodes.h
src/include/nodes/parsenodes.h

index 2c06609726f6ac0248d4ab2919e8b7c4dcc742f9..056530a657bc503ca04618c3b49cda5973a0cfc8 100644 (file)
@@ -50,6 +50,8 @@ my @no_equal;
 my @no_read;
 # node types we don't want read/write support for
 my @no_read_write;
+# node types we don't want any support functions for, just node tags
+my @nodetag_only;
 
 # types that are copied by straight assignment
 my @scalar_types = qw(
@@ -95,7 +97,10 @@ push @scalar_types, qw(EquivalenceClass* EquivalenceMember*);
 # currently not required.
 push @scalar_types, qw(QualCost);
 
-# Nodes from these input files don't need support functions, just node tags.
+# Nodes from these input files are automatically treated as nodetag_only.
+# In the future we might add explicit pg_node_attr labeling to some of these
+# files and remove them from this list, but for now this is the path of least
+# resistance.
 my @nodetag_only_files = qw(
   nodes/execnodes.h
   access/amapi.h
@@ -113,10 +118,8 @@ my @nodetag_only_files = qw(
 
 # XXX various things we are not publishing right now to stay level
 # with the manual system
-push @no_copy,  qw(CallContext InlineCodeBlock);
-push @no_equal, qw(CallContext InlineCodeBlock);
 push @no_read_write,
-  qw(AccessPriv AlterTableCmd CallContext CreateOpClassItem FunctionParameter InferClause InlineCodeBlock ObjectWithArgs OnConflictClause PartitionCmd RoleSpec VacuumRelation);
+  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
@@ -254,6 +257,10 @@ foreach my $infile (@ARGV)
                        {
                            push @no_read, $in_struct;
                        }
+                       elsif ($attr eq 'nodetag_only')
+                       {
+                           push @nodetag_only, $in_struct;
+                       }
                        elsif ($attr eq 'special_read_write')
                        {
                            # This attribute is called
@@ -314,13 +321,9 @@ foreach my $infile (@ARGV)
                    $node_type_info{$in_struct}->{field_types} = \%ft;
                    $node_type_info{$in_struct}->{field_attrs} = \%fa;
 
-                   # Exclude nodes in nodetag_only_files from support.
-                   if (elem $infile, @nodetag_only_files)
-                   {
-                       push @no_copy,       $in_struct;
-                       push @no_equal,      $in_struct;
-                       push @no_read_write, $in_struct;
-                   }
+                   # Propagate nodetag_only marking from files to nodes
+                   push @nodetag_only, $in_struct
+                     if (elem $infile, @nodetag_only_files);
 
                    # Propagate some node attributes from supertypes
                    if ($supertype)
@@ -515,6 +518,7 @@ print $eff $node_includes;
 foreach my $n (@node_types)
 {
    next if elem $n, @abstract_types;
+   next if elem $n, @nodetag_only;
    my $struct_no_copy  = (elem $n, @no_copy);
    my $struct_no_equal = (elem $n, @no_equal);
    next if $struct_no_copy && $struct_no_equal;
@@ -706,6 +710,7 @@ print $rff $node_includes;
 foreach my $n (@node_types)
 {
    next if elem $n, @abstract_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.
index adc549002a692d60ed7143cf3483a82ed227a3a1..c8ed4e055242f17eddbe0c7a1274659e22145964 100644 (file)
@@ -61,12 +61,17 @@ typedef enum NodeTag
  *
  * - no_read: Does not support nodeRead() at all.
  *
+ * - nodetag_only: Does not support copyObject(), equal(), outNode(),
+ *   or nodeRead().
+ *
  * - special_read_write: Has special treatment in outNode() and nodeRead().
  *
  * Node types can be supertypes of other types whether or not they are marked
  * abstract: if a node struct appears as the first field of another struct
  * type, then it is the supertype of that type.  The no_copy, no_equal, and
  * no_read node attributes are automatically inherited from the supertype.
+ * (Notice that nodetag_only does not inherit, so it's not quite equivalent
+ * to a combination of other attributes.)
  *
  * Valid node field attributes:
  *
index 0b6a7bb365043ac3d68e9f2e133b6d7aba2defbc..e2ad761768557affd1249e858759c2640b98da34 100644 (file)
@@ -3382,6 +3382,8 @@ typedef struct DoStmt
 
 typedef struct InlineCodeBlock
 {
+   pg_node_attr(nodetag_only)  /* this is not a member of parse trees */
+
    NodeTag     type;
    char       *source_text;    /* source text of anonymous code block */
    Oid         langOid;        /* OID of selected language */
@@ -3408,6 +3410,8 @@ typedef struct CallStmt
 
 typedef struct CallContext
 {
+   pg_node_attr(nodetag_only)  /* this is not a member of parse trees */
+
    NodeTag     type;
    bool        atomic;
 } CallContext;