On Thu, Feb 09, 2023 at 06:12:50PM -0500, Tom Lane wrote:
> I'm okay with the pathnodes.h changes --- although surely you don't need
> changes like this:
> 
> -     pg_node_attr(abstract)
> +     pg_node_attr(abstract, no_query_jumble)
> 
> "abstract" should already imply "no_query_jumble".

Okay, understood.  Following this string of thoughts, I am a bit
surprised for two cases, though:
- PartitionPruneStep.
- Plan.
Both are abstract and both are marked with no_equal.  I guess that
applying no_query_jumble to both of them is fine, and that's what you
mean?

> I wonder too if you could shorten the changes by making no_query_jumble
> an inheritable attribute, and then just applying it to Path and Plan.

Ah.  I did not catch what you meant here at first, but I think that I
do now.  Are you referring to the part of gen_node_support.pl where we
propagate properties when a node is a supertype?  This part would be
taken into account when a node is parsed but we find that its first
member is already tracked as a node:
        # Propagate some node attributes from supertypes
        if ($supertype)
        {
                push @no_copy, $in_struct
                  if elem $supertype, @no_copy;
                push @no_equal, $in_struct
                  if elem $supertype, @no_equal;
                push @no_read, $in_struct
                  if elem $supertype, @no_read;
+               push @no_query_jumble, $in_struct
+                 if elem $supertype, @no_query_jumble;
        }

A benefit of doing that would also discard all the Scan and Sort
nodes.  So like the other no_* attributes, it makes sense to force the
inheritance here.

> The changes in parsenodes.h seem wrong, except for RawStmt.  Those node
> types are used in parsed queries, aren't they?

RTEPermissionInfo is a recent addition, as of a61b1f7.  This commit
documents it as a plan node, still it is part of a Query while being
ignored in the query jumbling since its introduction, so I am a bit
confused by this one.

Anyway, none of these need to be included in the query jumbling
currently because they are ignored, but I'd be fine to generate their
code by default as they could become relevant if other nodes begin to
rely on them more heavily, as being part of queries.  Peter E. has
mentioned upthread that a few nodes should include more jumbling while
some other parts should be ignored.  This should be analyzed
separately because ~15 does not seem to be strictly right, either.

Attached is a patch refreshed with all that.  Feel free to ignore 0002
as that's just useful to enforce the tests to go through the jumbling
code.  The attached reaches 95.0% of line coverage after a check-world
in funcs.c.

Thoughts?
--
Michael
From 316df43f7574f54ff93606549167102e319f5473 Mon Sep 17 00:00:00 2001
From: Michael Paquier <mich...@paquier.xyz>
Date: Fri, 10 Feb 2023 11:15:24 +0900
Subject: [PATCH v2 1/2] Mark more nodes with node attribute no_query_jumble

This mostly covers Plan and Path nodes, which should never be included
in the jumbling because we ignore these in Query nodes.  no_query_jumble
is now an inherited attribute to be able to achieve that, like its read
and write counterparts.
---
 src/include/nodes/nodes.h             |  8 ++--
 src/include/nodes/parsenodes.h        |  5 +++
 src/include/nodes/pathnodes.h         | 54 ++++++++++++++-------------
 src/include/nodes/plannodes.h         | 16 ++++----
 src/include/nodes/primnodes.h         |  4 ++
 src/backend/nodes/gen_node_support.pl |  2 +
 6 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 75dfe1919d..e6cf520547 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -77,10 +77,10 @@ typedef enum NodeTag
  *
  * 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.)
+ * type, then it is the supertype of that type.  The no_copy, no_equal,
+ * no_query_jumble 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:
  *
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 855da99ec0..9c97148b69 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1728,9 +1728,14 @@ typedef struct TriggerTransition
  *
  * stmt_location/stmt_len identify the portion of the source text string
  * containing this raw statement (useful for multi-statement strings).
+ *
+ * This is irrelevant for query jumbling, as this is not used in parsed
+ * queries.
  */
 typedef struct RawStmt
 {
+	pg_node_attr(no_query_jumble)
+
 	NodeTag		type;
 	Node	   *stmt;			/* raw parse tree */
 	int			stmt_location;	/* start location, or -1 if unknown */
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 0d4b1ec4e4..be4d791212 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -94,7 +94,7 @@ typedef enum UpperRelationKind
  */
 typedef struct PlannerGlobal
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -194,7 +194,7 @@ typedef struct PlannerInfo PlannerInfo;
 
 struct PlannerInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -853,7 +853,7 @@ typedef enum RelOptKind
 
 typedef struct RelOptInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1098,7 +1098,7 @@ typedef struct IndexOptInfo IndexOptInfo;
 
 struct IndexOptInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1208,7 +1208,7 @@ struct IndexOptInfo
  */
 typedef struct ForeignKeyOptInfo
 {
-	pg_node_attr(custom_read_write, no_copy_equal, no_read)
+	pg_node_attr(custom_read_write, no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1258,7 +1258,7 @@ typedef struct ForeignKeyOptInfo
  */
 typedef struct StatisticExtInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1309,7 +1309,7 @@ typedef struct StatisticExtInfo
  */
 typedef struct JoinDomain
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1371,7 +1371,7 @@ typedef struct JoinDomain
  */
 typedef struct EquivalenceClass
 {
-	pg_node_attr(custom_read_write, no_copy_equal, no_read)
+	pg_node_attr(custom_read_write, no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1422,7 +1422,7 @@ typedef struct EquivalenceClass
  */
 typedef struct EquivalenceMember
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1455,7 +1455,7 @@ typedef struct EquivalenceMember
  */
 typedef struct PathKey
 {
-	pg_node_attr(no_read)
+	pg_node_attr(no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1503,7 +1503,7 @@ typedef enum VolatileFunctionStatus
  */
 typedef struct PathTarget
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1550,7 +1550,7 @@ typedef struct PathTarget
  */
 typedef struct ParamPathInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1596,7 +1596,7 @@ typedef struct ParamPathInfo
  */
 typedef struct Path
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1730,7 +1730,7 @@ typedef struct IndexPath
  */
 typedef struct IndexClause
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 	struct RestrictInfo *rinfo; /* original restriction or join clause */
@@ -2231,7 +2231,7 @@ typedef struct AggPath
 
 typedef struct GroupingSetData
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 	List	   *set;			/* grouping set as list of sortgrouprefs */
@@ -2240,7 +2240,7 @@ typedef struct GroupingSetData
 
 typedef struct RollupData
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 	List	   *groupClause;	/* applicable subset of parse->groupClause */
@@ -2509,7 +2509,7 @@ typedef struct LimitPath
 
 typedef struct RestrictInfo
 {
-	pg_node_attr(no_read)
+	pg_node_attr(no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -2724,6 +2724,8 @@ typedef struct MergeScanSelCache
 
 typedef struct PlaceHolderVar
 {
+	pg_node_attr(no_query_jumble)
+
 	Expr		xpr;
 
 	/* the represented expression */
@@ -2825,7 +2827,7 @@ typedef struct SpecialJoinInfo SpecialJoinInfo;
 
 struct SpecialJoinInfo
 {
-	pg_node_attr(no_read)
+	pg_node_attr(no_read, no_query_jumble)
 
 	NodeTag		type;
 	Relids		min_lefthand;	/* base+OJ relids in minimum LHS for join */
@@ -2853,7 +2855,7 @@ struct SpecialJoinInfo
  */
 typedef struct OuterJoinClauseInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 	RestrictInfo *rinfo;		/* a mergejoinable outer-join clause */
@@ -2892,6 +2894,8 @@ typedef struct OuterJoinClauseInfo
 
 typedef struct AppendRelInfo
 {
+	pg_node_attr(no_query_jumble)
+
 	NodeTag		type;
 
 	/*
@@ -2967,7 +2971,7 @@ typedef struct AppendRelInfo
  */
 typedef struct RowIdentityVarInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -3005,7 +3009,7 @@ typedef struct RowIdentityVarInfo
 
 typedef struct PlaceHolderInfo
 {
-	pg_node_attr(no_read)
+	pg_node_attr(no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -3038,7 +3042,7 @@ typedef struct PlaceHolderInfo
  */
 typedef struct MinMaxAggInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -3116,7 +3120,7 @@ typedef struct MinMaxAggInfo
  */
 typedef struct PlannerParamItem
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -3296,7 +3300,7 @@ typedef struct JoinCostWorkspace
  */
 typedef struct AggInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
@@ -3330,7 +3334,7 @@ typedef struct AggInfo
  */
 typedef struct AggTransInfo
 {
-	pg_node_attr(no_copy_equal, no_read)
+	pg_node_attr(no_copy_equal, no_read, no_query_jumble)
 
 	NodeTag		type;
 
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 4781a9c632..659bd05c0c 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -46,7 +46,7 @@
  */
 typedef struct PlannedStmt
 {
-	pg_node_attr(no_equal)
+	pg_node_attr(no_equal, no_query_jumble)
 
 	NodeTag		type;
 
@@ -122,7 +122,7 @@ typedef struct PlannedStmt
  */
 typedef struct Plan
 {
-	pg_node_attr(abstract, no_equal)
+	pg_node_attr(abstract, no_equal, no_query_jumble)
 
 	NodeTag		type;
 
@@ -813,7 +813,7 @@ typedef struct NestLoop
 
 typedef struct NestLoopParam
 {
-	pg_node_attr(no_equal)
+	pg_node_attr(no_equal, no_query_jumble)
 
 	NodeTag		type;
 	int			paramno;		/* number of the PARAM_EXEC Param to set */
@@ -1377,7 +1377,7 @@ typedef enum RowMarkType
  */
 typedef struct PlanRowMark
 {
-	pg_node_attr(no_equal)
+	pg_node_attr(no_equal, no_query_jumble)
 
 	NodeTag		type;
 	Index		rti;			/* range table index of markable relation */
@@ -1425,7 +1425,7 @@ typedef struct PlanRowMark
  */
 typedef struct PartitionPruneInfo
 {
-	pg_node_attr(no_equal)
+	pg_node_attr(no_equal, no_query_jumble)
 
 	NodeTag		type;
 	Bitmapset  *root_parent_relids;
@@ -1452,7 +1452,7 @@ typedef struct PartitionPruneInfo
  */
 typedef struct PartitionedRelPruneInfo
 {
-	pg_node_attr(no_equal)
+	pg_node_attr(no_equal, no_query_jumble)
 
 	NodeTag		type;
 
@@ -1495,7 +1495,7 @@ typedef struct PartitionedRelPruneInfo
  */
 typedef struct PartitionPruneStep
 {
-	pg_node_attr(abstract, no_equal)
+	pg_node_attr(abstract, no_equal, no_query_jumble)
 
 	NodeTag		type;
 	int			step_id;
@@ -1570,7 +1570,7 @@ typedef struct PartitionPruneStepCombine
  */
 typedef struct PlanInvalItem
 {
-	pg_node_attr(no_equal)
+	pg_node_attr(no_equal, no_query_jumble)
 
 	NodeTag		type;
 	int			cacheId;		/* a syscache ID, see utils/syscache.h */
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 6d740be5c0..1be1642d92 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -982,6 +982,8 @@ typedef struct SubLink
  */
 typedef struct SubPlan
 {
+	pg_node_attr(no_query_jumble)
+
 	Expr		xpr;
 	/* Fields copied from original SubLink: */
 	SubLinkType subLinkType;	/* see above */
@@ -1029,6 +1031,8 @@ typedef struct SubPlan
  */
 typedef struct AlternativeSubPlan
 {
+	pg_node_attr(no_query_jumble)
+
 	Expr		xpr;
 	List	   *subplans;		/* SubPlan(s) with equivalent results */
 } AlternativeSubPlan;
diff --git a/src/backend/nodes/gen_node_support.pl b/src/backend/nodes/gen_node_support.pl
index 19ed29657c..2e57db915b 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -422,6 +422,8 @@ foreach my $infile (@ARGV)
 						  if elem $supertype, @no_equal;
 						push @no_read, $in_struct
 						  if elem $supertype, @no_read;
+						push @no_query_jumble, $in_struct
+						  if elem $supertype, @no_query_jumble;
 					}
 				}
 
-- 
2.39.1

From 51bc070c098721fd91ae729408365a222c3d1959 Mon Sep 17 00:00:00 2001
From: Michael Paquier <mich...@paquier.xyz>
Date: Fri, 10 Feb 2023 11:21:57 +0900
Subject: [PATCH v2 2/2] Switch compute_query_id = regress to mean "on" and
 force it in pg_regress

This is just a tweak to force the tests to go through the query
jumbling.
---
 src/include/nodes/queryjumble.h      | 2 ++
 src/backend/commands/explain.c       | 2 +-
 src/backend/nodes/queryjumblefuncs.c | 2 +-
 src/test/regress/pg_regress.c        | 3 ++-
 doc/src/sgml/config.sgml             | 2 +-
 5 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/include/nodes/queryjumble.h b/src/include/nodes/queryjumble.h
index 204b8f74fd..3aa7d93255 100644
--- a/src/include/nodes/queryjumble.h
+++ b/src/include/nodes/queryjumble.h
@@ -80,6 +80,8 @@ IsQueryIdEnabled(void)
 		return false;
 	if (compute_query_id == COMPUTE_QUERY_ID_ON)
 		return true;
+	if (compute_query_id == COMPUTE_QUERY_ID_REGRESS)
+		return true;
 	return query_id_enabled;
 }
 
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index fbbf28cf06..5aba713348 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -777,7 +777,7 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc)
 	ExplainPrintSettings(es);
 
 	/*
-	 * COMPUTE_QUERY_ID_REGRESS means COMPUTE_QUERY_ID_AUTO, but we don't show
+	 * COMPUTE_QUERY_ID_REGRESS means COMPUTE_QUERY_ID_ON, but we don't show
 	 * the queryid in any of the EXPLAIN plans to keep stable the results
 	 * generated by regression test suites.
 	 */
diff --git a/src/backend/nodes/queryjumblefuncs.c b/src/backend/nodes/queryjumblefuncs.c
index d7fd72d70f..4d594106ec 100644
--- a/src/backend/nodes/queryjumblefuncs.c
+++ b/src/backend/nodes/queryjumblefuncs.c
@@ -257,7 +257,7 @@ _jumbleNode(JumbleState *jstate, Node *node)
 
 		default:
 			/* Only a warning, since we can stumble along anyway */
-			elog(WARNING, "unrecognized node type: %d",
+			elog(ERROR, "unrecognized node type: %d",
 				 (int) nodeTag(expr));
 			break;
 	}
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index 6cd5998b9d..d3aafa156c 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -1876,8 +1876,9 @@ create_database(const char *dbname)
 					 "ALTER DATABASE \"%s\" SET lc_numeric TO 'C';"
 					 "ALTER DATABASE \"%s\" SET lc_time TO 'C';"
 					 "ALTER DATABASE \"%s\" SET bytea_output TO 'hex';"
+					 "ALTER DATABASE \"%s\" SET compute_query_id TO 'regress';"
 					 "ALTER DATABASE \"%s\" SET timezone_abbreviations TO 'Default';",
-					 dbname, dbname, dbname, dbname, dbname, dbname);
+					 dbname, dbname, dbname, dbname, dbname, dbname, dbname);
 	psql_end_command(buf, "postgres");
 
 	/*
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 8c56b134a8..56f8dac286 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -8226,7 +8226,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
         <literal>on</literal> (always enabled), <literal>auto</literal>,
         which lets modules such as <xref linkend="pgstatstatements"/>
         automatically enable it, and <literal>regress</literal> which
-        has the same effect as <literal>auto</literal>, except that the
+        has the same effect as <literal>on</literal>, except that the
         query identifier is not shown in the <literal>EXPLAIN</literal> output
         in order to facilitate automated regression testing.
         The default is <literal>auto</literal>.
-- 
2.39.1

Attachment: signature.asc
Description: PGP signature

Reply via email to