From 213650dbee9962492bfdd65ce3ed61fee674e5b4 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Fri, 20 Mar 2026 19:42:27 +0900 Subject: [PATCH] Reject DEFINE variables not used in PATTERN DEFINE variables that do not appear in PATTERN are now rejected with an error at parse time. When DEFINE supports qualified column references (e.g. A.price), a DEFINE expression may reference other pattern variables. If the planner silently removes unused variables, those references become dangling, leading to incorrect evaluation. Rejecting at parse time avoids this class of bugs entirely. Remove filterDefineClause() from the planner and replace it with buildDefineVariableList(), which builds the variable name list without filtering. Update regression tests accordingly. --- src/backend/executor/execRPR.c | 5 +- src/backend/optimizer/plan/createplan.c | 15 ++--- src/backend/optimizer/plan/rpr.c | 34 ++-------- src/backend/parser/parse_rpr.c | 9 ++- src/include/optimizer/rpr.h | 4 +- src/test/regress/expected/rpr_base.out | 82 +++++-------------------- src/test/regress/sql/rpr_base.sql | 46 ++------------ 7 files changed, 43 insertions(+), 152 deletions(-) diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 06934b95da3..a0a462256ad 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -204,8 +204,7 @@ * IV-1. Entry Point * * create_windowagg_plan() (createplan.c) - * +-- collectPatternVariables() Collect variable names - * +-- filterDefineClause() Remove unused DEFINE entries + * +-- buildDefineVariableList() Build variable name list from DEFINE * +-- buildRPRPattern() NFA compilation (6 phases) * * IV-2. The 6 Phases of buildRPRPattern() @@ -1297,7 +1296,7 @@ * transformRPR parse_rpr.c Parser entry point * transformDefineClause parse_rpr.c DEFINE transformation * collectPatternVariables rpr.c Variable collection - * filterDefineClause rpr.c DEFINE filtering + * buildDefineVariableList rpr.c DEFINE variable list * buildRPRPattern rpr.c NFA compilation main * optimizeRPRPattern rpr.c AST optimization * fillRPRPattern rpr.c NFA element generation diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index da71e7f3d64..9ac24cc222d 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -2539,19 +2539,16 @@ create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path) ordNumCols++; } - /* Build RPR pattern and filter defineClause */ + /* Build RPR pattern and defineVariableList */ if (wc->rpPattern) { - List *patternVars; - /* - * Filter defineClause to include only variables used in PATTERN. This - * eliminates unnecessary DEFINE evaluations at runtime. + * Build defineVariableList from defineClause. The parser already + * rejects DEFINE variables not used in PATTERN, so no filtering is + * needed. */ - patternVars = collectPatternVariables(wc->rpPattern); - filteredDefineClause = filterDefineClause(wc->defineClause, - patternVars, - &defineVariableList); + buildDefineVariableList(wc->defineClause, &defineVariableList); + filteredDefineClause = wc->defineClause; /* Compile and optimize RPR patterns */ compiledPattern = buildRPRPattern(wc->rpPattern, diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 0b4d93b933e..85b1a00d095 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -1771,50 +1771,28 @@ collectPatternVariables(RPRPatternNode *pattern) } /* - * filterDefineClause - * Filter defineClause to include only variables used in PATTERN. + * buildDefineVariableList + * Build defineVariableList from defineClause. * - * This eliminates unnecessary DEFINE evaluations at runtime. - * Also builds defineVariableList from the filtered result. + * The parser already ensures that all DEFINE variables appear in PATTERN, + * so no filtering is needed here. * - * Returns filtered defineClause (list of TargetEntry). * Sets *defineVariableList to list of variable names (String nodes). */ -List * -filterDefineClause(List *defineClause, List *patternVars, - List **defineVariableList) +void +buildDefineVariableList(List *defineClause, List **defineVariableList) { - List *filteredDefineClause = NIL; ListCell *lc; - ListCell *lc2; *defineVariableList = NIL; - /* Filter defineClause: keep only variables used in PATTERN */ foreach(lc, defineClause) { TargetEntry *te = (TargetEntry *) lfirst(lc); - foreach(lc2, patternVars) - { - if (strcmp(strVal(lfirst(lc2)), te->resname) == 0) - { - filteredDefineClause = lappend(filteredDefineClause, te); - break; - } - } - } - - /* Build defineVariableList from filtered defineClause */ - foreach(lc, filteredDefineClause) - { - TargetEntry *te = (TargetEntry *) lfirst(lc); - *defineVariableList = lappend(*defineVariableList, makeString(pstrdup(te->resname))); } - - return filteredDefineClause; } /* diff --git a/src/backend/parser/parse_rpr.c b/src/backend/parser/parse_rpr.c index 92fef2d9ba7..55283ab4bbe 100644 --- a/src/backend/parser/parse_rpr.c +++ b/src/backend/parser/parse_rpr.c @@ -244,8 +244,11 @@ validateRPRPatternVarCount(ParseState *pstate, RPRPatternNode *node, } } if (!found) - *varNames = lappend(*varNames, - makeString(pstrdup(rt->name))); + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("DEFINE variable \"%s\" is not used in PATTERN", + rt->name), + parser_errposition(pstate, rt->location))); } } } @@ -265,7 +268,7 @@ validateRPRPatternVarCount(ParseState *pstate, RPRPatternNode *node, * 6. Marks column origins and assigns collation information * * Note: Variables not in DEFINE are evaluated as TRUE by the executor. - * Variables in DEFINE but not in PATTERN are filtered out by the planner. + * Variables in DEFINE but not in PATTERN are rejected as an error. * * XXX Pattern variable qualified column references in DEFINE (e.g. * "A.price") are not yet supported. Currently rejected by diff --git a/src/include/optimizer/rpr.h b/src/include/optimizer/rpr.h index fa2d075925c..f93a128096b 100644 --- a/src/include/optimizer/rpr.h +++ b/src/include/optimizer/rpr.h @@ -52,8 +52,8 @@ #define RPRElemCanSkip(e) ((e)->min == 0) extern List *collectPatternVariables(RPRPatternNode *pattern); -extern List *filterDefineClause(List *defineClause, List *patternVars, - List **defineVariableList); +extern void buildDefineVariableList(List *defineClause, + List **defineVariableList); extern RPRPattern *buildRPRPattern(RPRPatternNode *pattern, List *defineVariableList, RPSkipTo rpSkipTo, int frameOptions); diff --git a/src/test/regress/expected/rpr_base.out b/src/test/regress/expected/rpr_base.out index 50a9e7daea9..3168468d0ae 100644 --- a/src/test/regress/expected/rpr_base.out +++ b/src/test/regress/expected/rpr_base.out @@ -353,12 +353,9 @@ WINDOW w AS ( DEFINE A AS id > 0, B AS id > 5 -- B not in pattern ) ORDER BY id; - id | cnt -----+----- - 1 | 2 - 2 | 0 -(2 rows) - +ERROR: DEFINE variable "b" is not used in PATTERN +LINE 7: DEFINE A AS id > 0, B AS id > 5 -- B not in pattern + ^ DROP TABLE rpr_unused; -- ============================================================ -- FRAME Options Tests @@ -2860,9 +2857,9 @@ WINDOW w AS ( PATTERN (A+) DEFINE A AS val > 0, B AS B.val > 0 ); -ERROR: pattern variable qualified column reference "b.val" is not supported in DEFINE clause +ERROR: DEFINE variable "b" is not used in PATTERN LINE 7: DEFINE A AS val > 0, B AS B.val > 0 - ^ + ^ -- Expected: ERROR: pattern variable qualified column reference "b.val" is not supported -- FROM-clause range variable qualified name: not allowed (prohibited by ยง6.5) SELECT COUNT(*) OVER w @@ -2941,12 +2938,9 @@ WINDOW w AS ( DEFINE A AS val > 0, B AS val > 5, C AS val > 10 ) ORDER BY id; - id | val | cnt -----+-----+----- - 1 | 10 | 2 - 2 | 20 | 0 -(2 rows) - +ERROR: DEFINE variable "b" is not used in PATTERN +LINE 7: DEFINE A AS val > 0, B AS val > 5, C AS val > 10 + ^ DROP TABLE rpr_err; -- NULL handling CREATE TABLE rpr_null (id INT, val INT); @@ -5670,7 +5664,7 @@ DROP TABLE rpr_stress; -- Tests for error conditions in rpr.c CREATE TABLE rpr_errors (id INT, val INT); INSERT INTO rpr_errors VALUES (1, 10), (2, 20); --- Test: PATTERN variable without DEFINE (A), DEFINE variable not in PATTERN (B) +-- Test: DEFINE variable not in PATTERN (error) SELECT id, val, COUNT(*) OVER w FROM rpr_errors WINDOW w AS ( ORDER BY id @@ -5679,55 +5673,11 @@ WINDOW w AS ( DEFINE B AS TRUE ); - id | val | count -----+-----+------- - 1 | 10 | 0 - 2 | 20 | 0 -(2 rows) - --- Expected: Success - A is implicitly TRUE, B is filtered out --- Test: 3 variables in PATTERN, 253 in DEFINE (DEFINE filtering test) -SELECT COUNT(*) OVER w FROM rpr_errors -WINDOW w AS ( - ORDER BY id - ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING - PATTERN (V1 V2 V3) - DEFINE - V1 AS val > 0, V2 AS val > 0, V3 AS val > 0, V4 AS val > 0, V5 AS val > 0, V6 AS val > 0, V7 AS val > 0, V8 AS val > 0, V9 AS val > 0, V10 AS val > 0, - V11 AS val > 0, V12 AS val > 0, V13 AS val > 0, V14 AS val > 0, V15 AS val > 0, V16 AS val > 0, V17 AS val > 0, V18 AS val > 0, V19 AS val > 0, V20 AS val > 0, - V21 AS val > 0, V22 AS val > 0, V23 AS val > 0, V24 AS val > 0, V25 AS val > 0, V26 AS val > 0, V27 AS val > 0, V28 AS val > 0, V29 AS val > 0, V30 AS val > 0, - V31 AS val > 0, V32 AS val > 0, V33 AS val > 0, V34 AS val > 0, V35 AS val > 0, V36 AS val > 0, V37 AS val > 0, V38 AS val > 0, V39 AS val > 0, V40 AS val > 0, - V41 AS val > 0, V42 AS val > 0, V43 AS val > 0, V44 AS val > 0, V45 AS val > 0, V46 AS val > 0, V47 AS val > 0, V48 AS val > 0, V49 AS val > 0, V50 AS val > 0, - V51 AS val > 0, V52 AS val > 0, V53 AS val > 0, V54 AS val > 0, V55 AS val > 0, V56 AS val > 0, V57 AS val > 0, V58 AS val > 0, V59 AS val > 0, V60 AS val > 0, - V61 AS val > 0, V62 AS val > 0, V63 AS val > 0, V64 AS val > 0, V65 AS val > 0, V66 AS val > 0, V67 AS val > 0, V68 AS val > 0, V69 AS val > 0, V70 AS val > 0, - V71 AS val > 0, V72 AS val > 0, V73 AS val > 0, V74 AS val > 0, V75 AS val > 0, V76 AS val > 0, V77 AS val > 0, V78 AS val > 0, V79 AS val > 0, V80 AS val > 0, - V81 AS val > 0, V82 AS val > 0, V83 AS val > 0, V84 AS val > 0, V85 AS val > 0, V86 AS val > 0, V87 AS val > 0, V88 AS val > 0, V89 AS val > 0, V90 AS val > 0, - V91 AS val > 0, V92 AS val > 0, V93 AS val > 0, V94 AS val > 0, V95 AS val > 0, V96 AS val > 0, V97 AS val > 0, V98 AS val > 0, V99 AS val > 0, V100 AS val > 0, - V101 AS val > 0, V102 AS val > 0, V103 AS val > 0, V104 AS val > 0, V105 AS val > 0, V106 AS val > 0, V107 AS val > 0, V108 AS val > 0, V109 AS val > 0, V110 AS val > 0, - V111 AS val > 0, V112 AS val > 0, V113 AS val > 0, V114 AS val > 0, V115 AS val > 0, V116 AS val > 0, V117 AS val > 0, V118 AS val > 0, V119 AS val > 0, V120 AS val > 0, - V121 AS val > 0, V122 AS val > 0, V123 AS val > 0, V124 AS val > 0, V125 AS val > 0, V126 AS val > 0, V127 AS val > 0, V128 AS val > 0, V129 AS val > 0, V130 AS val > 0, - V131 AS val > 0, V132 AS val > 0, V133 AS val > 0, V134 AS val > 0, V135 AS val > 0, V136 AS val > 0, V137 AS val > 0, V138 AS val > 0, V139 AS val > 0, V140 AS val > 0, - V141 AS val > 0, V142 AS val > 0, V143 AS val > 0, V144 AS val > 0, V145 AS val > 0, V146 AS val > 0, V147 AS val > 0, V148 AS val > 0, V149 AS val > 0, V150 AS val > 0, - V151 AS val > 0, V152 AS val > 0, V153 AS val > 0, V154 AS val > 0, V155 AS val > 0, V156 AS val > 0, V157 AS val > 0, V158 AS val > 0, V159 AS val > 0, V160 AS val > 0, - V161 AS val > 0, V162 AS val > 0, V163 AS val > 0, V164 AS val > 0, V165 AS val > 0, V166 AS val > 0, V167 AS val > 0, V168 AS val > 0, V169 AS val > 0, V170 AS val > 0, - V171 AS val > 0, V172 AS val > 0, V173 AS val > 0, V174 AS val > 0, V175 AS val > 0, V176 AS val > 0, V177 AS val > 0, V178 AS val > 0, V179 AS val > 0, V180 AS val > 0, - V181 AS val > 0, V182 AS val > 0, V183 AS val > 0, V184 AS val > 0, V185 AS val > 0, V186 AS val > 0, V187 AS val > 0, V188 AS val > 0, V189 AS val > 0, V190 AS val > 0, - V191 AS val > 0, V192 AS val > 0, V193 AS val > 0, V194 AS val > 0, V195 AS val > 0, V196 AS val > 0, V197 AS val > 0, V198 AS val > 0, V199 AS val > 0, V200 AS val > 0, - V201 AS val > 0, V202 AS val > 0, V203 AS val > 0, V204 AS val > 0, V205 AS val > 0, V206 AS val > 0, V207 AS val > 0, V208 AS val > 0, V209 AS val > 0, V210 AS val > 0, - V211 AS val > 0, V212 AS val > 0, V213 AS val > 0, V214 AS val > 0, V215 AS val > 0, V216 AS val > 0, V217 AS val > 0, V218 AS val > 0, V219 AS val > 0, V220 AS val > 0, - V221 AS val > 0, V222 AS val > 0, V223 AS val > 0, V224 AS val > 0, V225 AS val > 0, V226 AS val > 0, V227 AS val > 0, V228 AS val > 0, V229 AS val > 0, V230 AS val > 0, - V231 AS val > 0, V232 AS val > 0, V233 AS val > 0, V234 AS val > 0, V235 AS val > 0, V236 AS val > 0, V237 AS val > 0, V238 AS val > 0, V239 AS val > 0, V240 AS val > 0, - V241 AS val > 0, V242 AS val > 0, V243 AS val > 0, V244 AS val > 0, V245 AS val > 0, V246 AS val > 0, V247 AS val > 0, V248 AS val > 0, V249 AS val > 0, V250 AS val > 0, - V251 AS val > 0, V252 AS val > 0, V253 AS val > 0 -); - count -------- - 0 - 0 -(2 rows) - --- Expected: Success - unused DEFINE variables are filtered out --- Test: 251 variables in PATTERN, 252 in DEFINE (boundary - should succeed) +ERROR: DEFINE variable "b" is not used in PATTERN +LINE 7: B AS TRUE + ^ +-- Expected: Error - B is not used in PATTERN +-- Test: 251 variables in PATTERN and DEFINE (boundary - should succeed) SELECT COUNT(*) OVER w FROM rpr_errors WINDOW w AS ( ORDER BY id @@ -5759,7 +5709,7 @@ WINDOW w AS ( V221 AS val > 0, V222 AS val > 0, V223 AS val > 0, V224 AS val > 0, V225 AS val > 0, V226 AS val > 0, V227 AS val > 0, V228 AS val > 0, V229 AS val > 0, V230 AS val > 0, V231 AS val > 0, V232 AS val > 0, V233 AS val > 0, V234 AS val > 0, V235 AS val > 0, V236 AS val > 0, V237 AS val > 0, V238 AS val > 0, V239 AS val > 0, V240 AS val > 0, V241 AS val > 0, V242 AS val > 0, V243 AS val > 0, V244 AS val > 0, V245 AS val > 0, V246 AS val > 0, V247 AS val > 0, V248 AS val > 0, V249 AS val > 0, V250 AS val > 0, - V251 AS val > 0, V252 AS val > 0 + V251 AS val > 0 ); count ------- @@ -5767,7 +5717,7 @@ WINDOW w AS ( 0 (2 rows) --- Expected: Success - unused DEFINE variables are filtered out +-- Expected: Success - exactly at RPR_VARID_MAX boundary -- Test: 252 variables in PATTERN, 251 in DEFINE (exceeds limit with implicit TRUE) SELECT COUNT(*) OVER w FROM rpr_errors WINDOW w AS ( diff --git a/src/test/regress/sql/rpr_base.sql b/src/test/regress/sql/rpr_base.sql index e54d54e400a..cf6c062ae85 100644 --- a/src/test/regress/sql/rpr_base.sql +++ b/src/test/regress/sql/rpr_base.sql @@ -3639,7 +3639,7 @@ DROP TABLE rpr_stress; CREATE TABLE rpr_errors (id INT, val INT); INSERT INTO rpr_errors VALUES (1, 10), (2, 20); --- Test: PATTERN variable without DEFINE (A), DEFINE variable not in PATTERN (B) +-- Test: DEFINE variable not in PATTERN (error) SELECT id, val, COUNT(*) OVER w FROM rpr_errors WINDOW w AS ( ORDER BY id @@ -3648,45 +3648,9 @@ WINDOW w AS ( DEFINE B AS TRUE ); --- Expected: Success - A is implicitly TRUE, B is filtered out +-- Expected: Error - B is not used in PATTERN --- Test: 3 variables in PATTERN, 253 in DEFINE (DEFINE filtering test) -SELECT COUNT(*) OVER w FROM rpr_errors -WINDOW w AS ( - ORDER BY id - ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING - PATTERN (V1 V2 V3) - DEFINE - V1 AS val > 0, V2 AS val > 0, V3 AS val > 0, V4 AS val > 0, V5 AS val > 0, V6 AS val > 0, V7 AS val > 0, V8 AS val > 0, V9 AS val > 0, V10 AS val > 0, - V11 AS val > 0, V12 AS val > 0, V13 AS val > 0, V14 AS val > 0, V15 AS val > 0, V16 AS val > 0, V17 AS val > 0, V18 AS val > 0, V19 AS val > 0, V20 AS val > 0, - V21 AS val > 0, V22 AS val > 0, V23 AS val > 0, V24 AS val > 0, V25 AS val > 0, V26 AS val > 0, V27 AS val > 0, V28 AS val > 0, V29 AS val > 0, V30 AS val > 0, - V31 AS val > 0, V32 AS val > 0, V33 AS val > 0, V34 AS val > 0, V35 AS val > 0, V36 AS val > 0, V37 AS val > 0, V38 AS val > 0, V39 AS val > 0, V40 AS val > 0, - V41 AS val > 0, V42 AS val > 0, V43 AS val > 0, V44 AS val > 0, V45 AS val > 0, V46 AS val > 0, V47 AS val > 0, V48 AS val > 0, V49 AS val > 0, V50 AS val > 0, - V51 AS val > 0, V52 AS val > 0, V53 AS val > 0, V54 AS val > 0, V55 AS val > 0, V56 AS val > 0, V57 AS val > 0, V58 AS val > 0, V59 AS val > 0, V60 AS val > 0, - V61 AS val > 0, V62 AS val > 0, V63 AS val > 0, V64 AS val > 0, V65 AS val > 0, V66 AS val > 0, V67 AS val > 0, V68 AS val > 0, V69 AS val > 0, V70 AS val > 0, - V71 AS val > 0, V72 AS val > 0, V73 AS val > 0, V74 AS val > 0, V75 AS val > 0, V76 AS val > 0, V77 AS val > 0, V78 AS val > 0, V79 AS val > 0, V80 AS val > 0, - V81 AS val > 0, V82 AS val > 0, V83 AS val > 0, V84 AS val > 0, V85 AS val > 0, V86 AS val > 0, V87 AS val > 0, V88 AS val > 0, V89 AS val > 0, V90 AS val > 0, - V91 AS val > 0, V92 AS val > 0, V93 AS val > 0, V94 AS val > 0, V95 AS val > 0, V96 AS val > 0, V97 AS val > 0, V98 AS val > 0, V99 AS val > 0, V100 AS val > 0, - V101 AS val > 0, V102 AS val > 0, V103 AS val > 0, V104 AS val > 0, V105 AS val > 0, V106 AS val > 0, V107 AS val > 0, V108 AS val > 0, V109 AS val > 0, V110 AS val > 0, - V111 AS val > 0, V112 AS val > 0, V113 AS val > 0, V114 AS val > 0, V115 AS val > 0, V116 AS val > 0, V117 AS val > 0, V118 AS val > 0, V119 AS val > 0, V120 AS val > 0, - V121 AS val > 0, V122 AS val > 0, V123 AS val > 0, V124 AS val > 0, V125 AS val > 0, V126 AS val > 0, V127 AS val > 0, V128 AS val > 0, V129 AS val > 0, V130 AS val > 0, - V131 AS val > 0, V132 AS val > 0, V133 AS val > 0, V134 AS val > 0, V135 AS val > 0, V136 AS val > 0, V137 AS val > 0, V138 AS val > 0, V139 AS val > 0, V140 AS val > 0, - V141 AS val > 0, V142 AS val > 0, V143 AS val > 0, V144 AS val > 0, V145 AS val > 0, V146 AS val > 0, V147 AS val > 0, V148 AS val > 0, V149 AS val > 0, V150 AS val > 0, - V151 AS val > 0, V152 AS val > 0, V153 AS val > 0, V154 AS val > 0, V155 AS val > 0, V156 AS val > 0, V157 AS val > 0, V158 AS val > 0, V159 AS val > 0, V160 AS val > 0, - V161 AS val > 0, V162 AS val > 0, V163 AS val > 0, V164 AS val > 0, V165 AS val > 0, V166 AS val > 0, V167 AS val > 0, V168 AS val > 0, V169 AS val > 0, V170 AS val > 0, - V171 AS val > 0, V172 AS val > 0, V173 AS val > 0, V174 AS val > 0, V175 AS val > 0, V176 AS val > 0, V177 AS val > 0, V178 AS val > 0, V179 AS val > 0, V180 AS val > 0, - V181 AS val > 0, V182 AS val > 0, V183 AS val > 0, V184 AS val > 0, V185 AS val > 0, V186 AS val > 0, V187 AS val > 0, V188 AS val > 0, V189 AS val > 0, V190 AS val > 0, - V191 AS val > 0, V192 AS val > 0, V193 AS val > 0, V194 AS val > 0, V195 AS val > 0, V196 AS val > 0, V197 AS val > 0, V198 AS val > 0, V199 AS val > 0, V200 AS val > 0, - V201 AS val > 0, V202 AS val > 0, V203 AS val > 0, V204 AS val > 0, V205 AS val > 0, V206 AS val > 0, V207 AS val > 0, V208 AS val > 0, V209 AS val > 0, V210 AS val > 0, - V211 AS val > 0, V212 AS val > 0, V213 AS val > 0, V214 AS val > 0, V215 AS val > 0, V216 AS val > 0, V217 AS val > 0, V218 AS val > 0, V219 AS val > 0, V220 AS val > 0, - V221 AS val > 0, V222 AS val > 0, V223 AS val > 0, V224 AS val > 0, V225 AS val > 0, V226 AS val > 0, V227 AS val > 0, V228 AS val > 0, V229 AS val > 0, V230 AS val > 0, - V231 AS val > 0, V232 AS val > 0, V233 AS val > 0, V234 AS val > 0, V235 AS val > 0, V236 AS val > 0, V237 AS val > 0, V238 AS val > 0, V239 AS val > 0, V240 AS val > 0, - V241 AS val > 0, V242 AS val > 0, V243 AS val > 0, V244 AS val > 0, V245 AS val > 0, V246 AS val > 0, V247 AS val > 0, V248 AS val > 0, V249 AS val > 0, V250 AS val > 0, - V251 AS val > 0, V252 AS val > 0, V253 AS val > 0 -); --- Expected: Success - unused DEFINE variables are filtered out - --- Test: 251 variables in PATTERN, 252 in DEFINE (boundary - should succeed) +-- Test: 251 variables in PATTERN and DEFINE (boundary - should succeed) SELECT COUNT(*) OVER w FROM rpr_errors WINDOW w AS ( ORDER BY id @@ -3718,9 +3682,9 @@ WINDOW w AS ( V221 AS val > 0, V222 AS val > 0, V223 AS val > 0, V224 AS val > 0, V225 AS val > 0, V226 AS val > 0, V227 AS val > 0, V228 AS val > 0, V229 AS val > 0, V230 AS val > 0, V231 AS val > 0, V232 AS val > 0, V233 AS val > 0, V234 AS val > 0, V235 AS val > 0, V236 AS val > 0, V237 AS val > 0, V238 AS val > 0, V239 AS val > 0, V240 AS val > 0, V241 AS val > 0, V242 AS val > 0, V243 AS val > 0, V244 AS val > 0, V245 AS val > 0, V246 AS val > 0, V247 AS val > 0, V248 AS val > 0, V249 AS val > 0, V250 AS val > 0, - V251 AS val > 0, V252 AS val > 0 + V251 AS val > 0 ); --- Expected: Success - unused DEFINE variables are filtered out +-- Expected: Success - exactly at RPR_VARID_MAX boundary -- Test: 252 variables in PATTERN, 251 in DEFINE (exceeds limit with implicit TRUE) SELECT COUNT(*) OVER w FROM rpr_errors -- 2.50.1 (Apple Git-155)