From 5fefcc3ca8eb2870788495038fe70094c87e946b Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Fri, 17 Jul 2026 06:52:25 +0900 Subject: [PATCH] Follow local conventions in row pattern recognition additions Several additions went in without regard to the conventions of the files they landed in. createplan.c included common/int.h ahead of the access/ headers and optimizer/rpr.h after optimizer/subselect.h; execExprInterp.c included common/int.h between the two access/ headers. Sort them into place. (createplan.c still uses common/int.h here, through pg_add_s64_overflow in visit_nav_plan; the later navigation rework removes that use and drops the include there.) execExpr.c placed case T_RPRNavExpr after T_MergeSupportFunc and T_SubscriptingRef, though the switch documents that cases follow enum NodeTag order and T_RPRNavExpr precedes both. typedefs.list had NFALengthStats after the Next* entries, though it sorts before them in C collation. RPRPattern lacked no_query_jumble, so gen_node_support emitted a jumble function hashing raw pointers for a plan-only node that a Query can never reach. Two EXPLAIN ANALYZE tests in rpr_explain.sql ran bare instead of through rpr_explain_filter, fixing "Maximum Storage: 17kB" in the expected output -- the very value the filter exists to normalize -- and they lacked BUFFERS OFF, unlike every other EXPLAIN in the file. No functional change. --- src/backend/executor/execExpr.c | 42 +++++++++++------------ src/backend/executor/execExprInterp.c | 2 +- src/backend/optimizer/plan/createplan.c | 4 +-- src/include/nodes/plannodes.h | 6 ++-- src/test/regress/expected/rpr_explain.out | 18 +++++----- src/test/regress/sql/rpr_explain.sql | 10 +++--- src/tools/pgindent/typedefs.list | 2 +- 7 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index 30367825033..8e812fdcdc5 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -1168,27 +1168,6 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } - case T_MergeSupportFunc: - { - /* must be in a MERGE, else something messed up */ - if (!state->parent || - !IsA(state->parent, ModifyTableState) || - ((ModifyTableState *) state->parent)->operation != CMD_MERGE) - elog(ERROR, "MergeSupportFunc found in non-merge plan node"); - - scratch.opcode = EEOP_MERGE_SUPPORT_FUNC; - ExprEvalPushStep(state, &scratch); - break; - } - - case T_SubscriptingRef: - { - SubscriptingRef *sbsref = (SubscriptingRef *) node; - - ExecInitSubscriptingRef(&scratch, sbsref, state, resv, resnull); - break; - } - case T_RPRNavExpr: { /* @@ -1281,6 +1260,27 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } + case T_MergeSupportFunc: + { + /* must be in a MERGE, else something messed up */ + if (!state->parent || + !IsA(state->parent, ModifyTableState) || + ((ModifyTableState *) state->parent)->operation != CMD_MERGE) + elog(ERROR, "MergeSupportFunc found in non-merge plan node"); + + scratch.opcode = EEOP_MERGE_SUPPORT_FUNC; + ExprEvalPushStep(state, &scratch); + break; + } + + case T_SubscriptingRef: + { + SubscriptingRef *sbsref = (SubscriptingRef *) node; + + ExecInitSubscriptingRef(&scratch, sbsref, state, resv, resnull); + break; + } + case T_FuncExpr: { FuncExpr *func = (FuncExpr *) node; diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index 5b6281e9e31..ca28b7b152c 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -57,10 +57,10 @@ #include "postgres.h" #include "access/heaptoast.h" -#include "common/int.h" #include "access/tupconvert.h" #include "catalog/pg_type.h" #include "commands/sequence.h" +#include "common/int.h" #include "executor/execExpr.h" #include "executor/nodeSubplan.h" #include "executor/nodeWindowAgg.h" diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index c4e3ac0ca27..9da765c3951 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -16,10 +16,10 @@ */ #include "postgres.h" -#include "common/int.h" #include "access/sysattr.h" #include "access/transam.h" #include "catalog/pg_class.h" +#include "common/int.h" #include "foreign/fdwapi.h" #include "miscadmin.h" #include "nodes/extensible.h" @@ -36,8 +36,8 @@ #include "optimizer/planmain.h" #include "optimizer/prep.h" #include "optimizer/restrictinfo.h" -#include "optimizer/subselect.h" #include "optimizer/rpr.h" +#include "optimizer/subselect.h" #include "optimizer/tlist.h" #include "parser/parse_clause.h" #include "parser/parsetree.h" diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index e124ffc02ee..d8fc3615246 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -1290,9 +1290,11 @@ typedef struct RPRPattern * hand-written copy (custom_copy_equal). It is never compared with * equal(): equal() routines are generated only for parse/rewrite-level * nodes, not for plan nodes, so there is nothing to compare it against - * and equal support is suppressed with no_equal. + * and equal support is suppressed with no_equal. It is not reachable + * from a Query either, so query jumbling has nothing to do here and is + * suppressed with no_query_jumble. */ - pg_node_attr(custom_copy_equal, custom_read_write, no_equal) + pg_node_attr(custom_copy_equal, custom_read_write, no_equal, no_query_jumble) NodeTag type; /* T_RPRPattern */ int numVars; /* number of pattern variables */ diff --git a/src/test/regress/expected/rpr_explain.out b/src/test/regress/expected/rpr_explain.out index 687d5dd2b2a..d83146d77cf 100644 --- a/src/test/regress/expected/rpr_explain.out +++ b/src/test/regress/expected/rpr_explain.out @@ -6210,15 +6210,16 @@ EXPLAIN (COSTS OFF) EXECUTE test_overflow_lookback(4611686018427387904, 46116860 -> Function Scan on generate_series s (5 rows) -EXPLAIN (COSTS OFF, ANALYZE, TIMING OFF, SUMMARY OFF) - EXECUTE test_overflow_lookback(4611686018427387904, 4611686018427387904); - QUERY PLAN +SELECT rpr_explain_filter(' +EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, TIMING OFF, SUMMARY OFF) + EXECUTE test_overflow_lookback(4611686018427387904, 4611686018427387904)'); + rpr_explain_filter ---------------------------------------------------------------------- WindowAgg (actual rows=10.00 loops=1) Window: w AS (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) Pattern: a+ Nav Mark Lookback: retain all - Storage: Memory Maximum Storage: 17kB + Storage: Memory Maximum Storage: NkB NFA States: 1 peak, 11 total, 0 merged NFA Contexts: 2 peak, 11 total, 10 pruned NFA: 0 matched, 0 mismatched @@ -6237,16 +6238,17 @@ WINDOW w AS ( DEFINE A AS NEXT(FIRST(v, $1), $2) IS NOT NULL ); SET plan_cache_mode = force_generic_plan; -EXPLAIN (COSTS OFF, ANALYZE, TIMING OFF, SUMMARY OFF) - EXECUTE test_overflow_lookahead(4611686018427387904, 4611686018427387904); - QUERY PLAN +SELECT rpr_explain_filter(' +EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, TIMING OFF, SUMMARY OFF) + EXECUTE test_overflow_lookahead(4611686018427387904, 4611686018427387904)'); + rpr_explain_filter ---------------------------------------------------------------------- WindowAgg (actual rows=10.00 loops=1) Window: w AS (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) Pattern: a+ Nav Mark Lookback: 0 Nav Mark Lookahead: infinite - Storage: Memory Maximum Storage: 17kB + Storage: Memory Maximum Storage: NkB NFA States: 1 peak, 11 total, 0 merged NFA Contexts: 2 peak, 11 total, 10 pruned NFA: 0 matched, 0 mismatched diff --git a/src/test/regress/sql/rpr_explain.sql b/src/test/regress/sql/rpr_explain.sql index 2515c4cbec9..af79a2521c7 100644 --- a/src/test/regress/sql/rpr_explain.sql +++ b/src/test/regress/sql/rpr_explain.sql @@ -3522,8 +3522,9 @@ WINDOW w AS ( ); SET plan_cache_mode = force_generic_plan; EXPLAIN (COSTS OFF) EXECUTE test_overflow_lookback(4611686018427387904, 4611686018427387904); -EXPLAIN (COSTS OFF, ANALYZE, TIMING OFF, SUMMARY OFF) - EXECUTE test_overflow_lookback(4611686018427387904, 4611686018427387904); +SELECT rpr_explain_filter(' +EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, TIMING OFF, SUMMARY OFF) + EXECUTE test_overflow_lookback(4611686018427387904, 4611686018427387904)'); RESET plan_cache_mode; DEALLOCATE test_overflow_lookback; @@ -3537,8 +3538,9 @@ WINDOW w AS ( DEFINE A AS NEXT(FIRST(v, $1), $2) IS NOT NULL ); SET plan_cache_mode = force_generic_plan; -EXPLAIN (COSTS OFF, ANALYZE, TIMING OFF, SUMMARY OFF) - EXECUTE test_overflow_lookahead(4611686018427387904, 4611686018427387904); +SELECT rpr_explain_filter(' +EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, TIMING OFF, SUMMARY OFF) + EXECUTE test_overflow_lookahead(4611686018427387904, 4611686018427387904)'); RESET plan_cache_mode; DEALLOCATE test_overflow_lookahead; diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 78edf8092eb..11888d86b35 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -1824,6 +1824,7 @@ MultirangeType NDBOX NDistinctParseState NDistinctSemanticState +NFALengthStats NLSVERSIONINFOEX NODE NTSTATUS @@ -1853,7 +1854,6 @@ NewConstraint NextSampleBlock_function NextSampleTuple_function NextValueExpr -NFALengthStats Node NodeInstrumentation NodeTag -- 2.50.1 (Apple Git-155)