src/backend/parser/parse_rpr.c - Coverage Report

← Back to Overview

# src/backend/parser/parse_rpr.c

Coverage: 161/161 lines (100.0%)
Total Lines
161
modified
Covered
161
100.0%
Uncovered
0
0.0%
Keyboard navigation
transformRPR() lines 75-185
Modified Lines Coverage: 30/30 lines (100.0%)

Line | Hits | Source | Commit
--- | --- | --- | ---
75 | 6259 | transformRPR(ParseState *pstate, WindowClause *wc, WindowDef *windef, | c54ba27Row pattern recognition patch (parse/analysis).
76 | - | List **targetlist) | c54ba27Row pattern recognition patch (parse/analysis).
77 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
78 | - | /* Window definition must exist when called */ | c54ba27Row pattern recognition patch (parse/analysis).
79 | 6259 | Assert(windef != NULL); | c54ba27Row pattern recognition patch (parse/analysis).
80 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
81 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
82 | - | * Row Pattern Common Syntax clause exists? | c54ba27Row pattern recognition patch (parse/analysis).
83 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
84 | 6259 | if (windef->rpCommonSyntax == NULL) | c54ba27Row pattern recognition patch (parse/analysis).
85 | - | return; | c54ba27Row pattern recognition patch (parse/analysis).
86 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
87 | - | /* Check Frame options */ | c54ba27Row pattern recognition patch (parse/analysis).
88 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
89 | - | /* Frame type must be "ROW" */ | c54ba27Row pattern recognition patch (parse/analysis).
90 | 4157 | if (wc->frameOptions & FRAMEOPTION_GROUPS) | c54ba27Row pattern recognition patch (parse/analysis).
91 | 8 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
92 | - | errcode(ERRCODE_WINDOWING_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
93 | - | errmsg("cannot use FRAME option GROUPS with row pattern recognition"), | c54ba27Row pattern recognition patch (parse/analysis).
94 | - | errhint("Use ROWS instead."), | c54ba27Row pattern recognition patch (parse/analysis).
95 | - | parser_errposition(pstate, | c54ba27Row pattern recognition patch (parse/analysis).
96 | - | windef->frameLocation >= 0 ? | c54ba27Row pattern recognition patch (parse/analysis).
97 | - | windef->frameLocation : windef->location)); | c54ba27Row pattern recognition patch (parse/analysis).
98 | 4149 | if (wc->frameOptions & FRAMEOPTION_RANGE) | c54ba27Row pattern recognition patch (parse/analysis).
99 | 12 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
100 | - | errcode(ERRCODE_WINDOWING_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
101 | - | errmsg("cannot use FRAME option RANGE with row pattern recognition"), | c54ba27Row pattern recognition patch (parse/analysis).
102 | - | errhint("Use ROWS instead."), | c54ba27Row pattern recognition patch (parse/analysis).
103 | - | parser_errposition(pstate, | c54ba27Row pattern recognition patch (parse/analysis).
104 | - | windef->frameLocation >= 0 ? | c54ba27Row pattern recognition patch (parse/analysis).
105 | - | windef->frameLocation : windef->location)); | c54ba27Row pattern recognition patch (parse/analysis).
106 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
107 | - | /* Frame must start at current row */ | c54ba27Row pattern recognition patch (parse/analysis).
108 | 4137 | if ((wc->frameOptions & FRAMEOPTION_START_CURRENT_ROW) == 0) | c54ba27Row pattern recognition patch (parse/analysis).
109 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
110 | 12 | const char *frameType = "ROWS"; | c54ba27Row pattern recognition patch (parse/analysis).
111 | 12 | const char *startBound = "unknown"; | c54ba27Row pattern recognition patch (parse/analysis).
112 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
113 | - | /* Determine current start bound */ | c54ba27Row pattern recognition patch (parse/analysis).
114 | 12 | if (wc->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) | c54ba27Row pattern recognition patch (parse/analysis).
115 | - | startBound = "UNBOUNDED PRECEDING"; | c54ba27Row pattern recognition patch (parse/analysis).
116 | 8 | else if (wc->frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING) | c54ba27Row pattern recognition patch (parse/analysis).
117 | - | startBound = "offset PRECEDING"; | c54ba27Row pattern recognition patch (parse/analysis).
118 | 4 | else if (wc->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING) | c54ba27Row pattern recognition patch (parse/analysis).
119 | 4 | startBound = "offset FOLLOWING"; | c54ba27Row pattern recognition patch (parse/analysis).
120 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
121 | - | /* At least one valid frame start option should be set */ | c54ba27Row pattern recognition patch (parse/analysis).
122 | 12 | Assert((wc->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) || | c54ba27Row pattern recognition patch (parse/analysis).
123 | - | (wc->frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING) || | c54ba27Row pattern recognition patch (parse/analysis).
124 | - | (wc->frameOptions & FRAMEOPTION_START_OFFSET_FOLLOWING)); | c54ba27Row pattern recognition patch (parse/analysis).
125 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
126 | 12 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
127 | - | errcode(ERRCODE_WINDOWING_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
128 | - | errmsg("FRAME must start at CURRENT ROW when using row pattern recognition"), | c54ba27Row pattern recognition patch (parse/analysis).
129 | - | errdetail("Current frame starts with %s.", startBound), | c54ba27Row pattern recognition patch (parse/analysis).
130 | - | errhint("Use: %s BETWEEN CURRENT ROW AND ...", frameType), | c54ba27Row pattern recognition patch (parse/analysis).
131 | - | parser_errposition(pstate, windef->frameLocation >= 0 ? windef->frameLocation : windef->location)); | c54ba27Row pattern recognition patch (parse/analysis).
132 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
133 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
134 | - | /* EXCLUDE options are not permitted */ | c54ba27Row pattern recognition patch (parse/analysis).
135 | 4125 | if ((wc->frameOptions & FRAMEOPTION_EXCLUSION) != 0) | c54ba27Row pattern recognition patch (parse/analysis).
136 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
137 | 12 | const char *excludeType = "EXCLUDE"; | c54ba27Row pattern recognition patch (parse/analysis).
138 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
139 | - | /* Determine which EXCLUDE option was used */ | c54ba27Row pattern recognition patch (parse/analysis).
140 | 12 | if (wc->frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) | c54ba27Row pattern recognition patch (parse/analysis).
141 | - | excludeType = "EXCLUDE CURRENT ROW"; | c54ba27Row pattern recognition patch (parse/analysis).
142 | 8 | else if (wc->frameOptions & FRAMEOPTION_EXCLUDE_GROUP) | c54ba27Row pattern recognition patch (parse/analysis).
143 | - | excludeType = "EXCLUDE GROUP"; | c54ba27Row pattern recognition patch (parse/analysis).
144 | 4 | else if (wc->frameOptions & FRAMEOPTION_EXCLUDE_TIES) | c54ba27Row pattern recognition patch (parse/analysis).
145 | 4 | excludeType = "EXCLUDE TIES"; | c54ba27Row pattern recognition patch (parse/analysis).
146 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
147 | - | /* At least one valid exclude option should be set */ | c54ba27Row pattern recognition patch (parse/analysis).
148 | 12 | Assert((wc->frameOptions & FRAMEOPTION_EXCLUDE_CURRENT_ROW) || | c54ba27Row pattern recognition patch (parse/analysis).
149 | - | (wc->frameOptions & FRAMEOPTION_EXCLUDE_GROUP) || | c54ba27Row pattern recognition patch (parse/analysis).
150 | - | (wc->frameOptions & FRAMEOPTION_EXCLUDE_TIES)); | c54ba27Row pattern recognition patch (parse/analysis).
151 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
152 | 12 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
153 | - | errcode(ERRCODE_WINDOWING_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
154 | - | errmsg("cannot use EXCLUDE options with row pattern recognition"), | c54ba27Row pattern recognition patch (parse/analysis).
155 | - | errdetail("Frame definition includes %s.", excludeType), | c54ba27Row pattern recognition patch (parse/analysis).
156 | - | errhint("Remove the EXCLUDE clause from the window definition."), | c54ba27Row pattern recognition patch (parse/analysis).
157 | - | parser_errposition(pstate, windef->excludeLocation >= 0 ? windef->excludeLocation : windef->location)); | c54ba27Row pattern recognition patch (parse/analysis).
158 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
159 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
160 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
161 | - | * The standard allows only UNBOUNDED FOLLOWING or a positive offset | c54ba27Row pattern recognition patch (parse/analysis).
162 | - | * FOLLOWING as the frame end. The equivalent 0 FOLLOWING spelling is | c54ba27Row pattern recognition patch (parse/analysis).
163 | - | * caught at runtime in calculate_frame_offsets(). | c54ba27Row pattern recognition patch (parse/analysis).
164 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
165 | 4113 | if (wc->frameOptions & FRAMEOPTION_END_CURRENT_ROW) | c54ba27Row pattern recognition patch (parse/analysis).
166 | 4 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
167 | - | errcode(ERRCODE_WINDOWING_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
168 | - | errmsg("cannot use CURRENT ROW as frame end with row pattern recognition"), | c54ba27Row pattern recognition patch (parse/analysis).
169 | - | errhint("Use UNBOUNDED FOLLOWING or a positive offset FOLLOWING."), | c54ba27Row pattern recognition patch (parse/analysis).
170 | - | parser_errposition(pstate, | c54ba27Row pattern recognition patch (parse/analysis).
171 | - | windef->frameLocation >= 0 ? | c54ba27Row pattern recognition patch (parse/analysis).
172 | - | windef->frameLocation : windef->location)); | c54ba27Row pattern recognition patch (parse/analysis).
173 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
174 | - | /* Assign AFTER MATCH SKIP TO flag */ | c54ba27Row pattern recognition patch (parse/analysis).
175 | 4109 | wc->rpSkipTo = windef->rpCommonSyntax->rpSkipTo; | c54ba27Row pattern recognition patch (parse/analysis).
176 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
177 | - | /* Assign INITIAL flag */ | c54ba27Row pattern recognition patch (parse/analysis).
178 | 4109 | wc->initial = windef->rpCommonSyntax->initial; | c54ba27Row pattern recognition patch (parse/analysis).
179 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
180 | - | /* Transform DEFINE clause into list of TargetEntry's */ | c54ba27Row pattern recognition patch (parse/analysis).
181 | 4109 | wc->defineClause = transformDefineClause(pstate, windef, targetlist); | 4cf9108Further tidy up row pattern recognition plumbing
182 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
183 | - | /* Store PATTERN parse tree for deparsing */ | 9c7e5bcImprove comments, documentation, and naming for row pattern recognition
184 | 3797 | wc->rpPattern = windef->rpCommonSyntax->rpPattern; | c54ba27Row pattern recognition patch (parse/analysis).
185 | - | } | c54ba27Row pattern recognition patch (parse/analysis).

validateRPRPatternVarCount() lines 201-261
Modified Lines Coverage: 14/14 lines (100.0%)

Line | Hits | Source | Commit
--- | --- | --- | ---
201 | 19903 | validateRPRPatternVarCount(ParseState *pstate, RPRPatternNode *node, | c54ba27Row pattern recognition patch (parse/analysis).
202 | - | List **varNames) | 7a69cb8Refactor transformDefineClause in row pattern recognition
203 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
204 | - | /* Pattern node must exist - parser always provides non-NULL root */ | c54ba27Row pattern recognition patch (parse/analysis).
205 | 19903 | Assert(node != NULL); | c54ba27Row pattern recognition patch (parse/analysis).
206 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
207 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
208 | - | * trailing_alt is a transient grammar flag; splitRPRTrailingAlt must have | c54ba27Row pattern recognition patch (parse/analysis).
209 | - | * cleared it on every node before the pattern reaches parse analysis. | c54ba27Row pattern recognition patch (parse/analysis).
210 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
211 | 19903 | Assert(!node->trailing_alt); | c54ba27Row pattern recognition patch (parse/analysis).
212 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
213 | 19903 | check_stack_depth(); | c54ba27Row pattern recognition patch (parse/analysis).
214 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
215 | 19903 | switch (node->nodeType) | c54ba27Row pattern recognition patch (parse/analysis).
216 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
217 | - | case RPR_PATTERN_VAR: | c54ba27Row pattern recognition patch (parse/analysis).
218 | - | /* Add variable name if not already in list */ | c54ba27Row pattern recognition patch (parse/analysis).
219 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
220 | - | bool found = false; | c54ba27Row pattern recognition patch (parse/analysis).
221 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
222 | 251251 | foreach_node(String, varname, *varNames) | c54ba27Row pattern recognition patch (parse/analysis).
223 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
224 | 240562 | if (strcmp(strVal(varname), node->varName) == 0) | c54ba27Row pattern recognition patch (parse/analysis).
225 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
226 | - | found = true; | c54ba27Row pattern recognition patch (parse/analysis).
227 | - | break; | c54ba27Row pattern recognition patch (parse/analysis).
228 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
229 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
230 | 11573 | if (!found) | c54ba27Row pattern recognition patch (parse/analysis).
231 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
232 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
233 | - | * Check against RPR_VARID_MAX before adding. varId | c54ba27Row pattern recognition patch (parse/analysis).
234 | - | * values run 0 to RPR_VARID_MAX inclusive, so the next | c54ba27Row pattern recognition patch (parse/analysis).
235 | - | * varId to be assigned (the current list length) must not | c54ba27Row pattern recognition patch (parse/analysis).
236 | - | * exceed it. | c54ba27Row pattern recognition patch (parse/analysis).
237 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
238 | 10689 | if (list_length(*varNames) > RPR_VARID_MAX) | c54ba27Row pattern recognition patch (parse/analysis).
239 | 4 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
240 | - | errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), | c54ba27Row pattern recognition patch (parse/analysis).
241 | - | errmsg("too many pattern variables"), | c54ba27Row pattern recognition patch (parse/analysis).
242 | - | errdetail("Maximum is %d.", RPR_VARID_MAX + 1), | c54ba27Row pattern recognition patch (parse/analysis).
243 | - | parser_errposition(pstate, | c54ba27Row pattern recognition patch (parse/analysis).
244 | - | exprLocation((Node *) node))); | c54ba27Row pattern recognition patch (parse/analysis).
245 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
246 | 10685 | *varNames = lappend(*varNames, makeString(pstrdup(node->varName))); | c54ba27Row pattern recognition patch (parse/analysis).
247 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
248 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
249 | - | break; | c54ba27Row pattern recognition patch (parse/analysis).
250 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
251 | - | case RPR_PATTERN_SEQ: | c54ba27Row pattern recognition patch (parse/analysis).
252 | - | case RPR_PATTERN_ALT: | c54ba27Row pattern recognition patch (parse/analysis).
253 | - | case RPR_PATTERN_GROUP: | c54ba27Row pattern recognition patch (parse/analysis).
254 | - | /* Recurse into children */ | c54ba27Row pattern recognition patch (parse/analysis).
255 | 24120 | foreach_node(RPRPatternNode, child, node->children) | c54ba27Row pattern recognition patch (parse/analysis).
256 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
257 | 15794 | validateRPRPatternVarCount(pstate, child, varNames); | 7a69cb8Refactor transformDefineClause in row pattern recognition
258 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
259 | - | break; | c54ba27Row pattern recognition patch (parse/analysis).
260 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
261 | 19895 | } | c54ba27Row pattern recognition patch (parse/analysis).

transformDefineClause() lines 275-429
Modified Lines Coverage: 50/50 lines (100.0%)

Line | Hits | Source | Commit
--- | --- | --- | ---
275 | 4109 | transformDefineClause(ParseState *pstate, WindowDef *windef, | 4cf9108Further tidy up row pattern recognition plumbing
276 | - | List **targetlist) | c54ba27Row pattern recognition patch (parse/analysis).
277 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
278 | 4109 | List *defineClause = NIL; | c54ba27Row pattern recognition patch (parse/analysis).
279 | 4109 | List *patternVarNames = NIL; | c54ba27Row pattern recognition patch (parse/analysis).
280 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
281 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
282 | - | * If Row Definition Common Syntax exists, DEFINE clause must exist. (the | c54ba27Row pattern recognition patch (parse/analysis).
283 | - | * raw parser should have already checked it.) | c54ba27Row pattern recognition patch (parse/analysis).
284 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
285 | 4109 | Assert(windef->rpCommonSyntax->rpDefs != NULL); | c54ba27Row pattern recognition patch (parse/analysis).
286 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
287 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
288 | - | * Validate PATTERN variable count and collect the PATTERN variable names | 7a69cb8Refactor transformDefineClause in row pattern recognition
289 | - | * for transformColumnRef. | 7a69cb8Refactor transformDefineClause in row pattern recognition
290 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
291 | 4109 | validateRPRPatternVarCount(pstate, windef->rpCommonSyntax->rpPattern, | c54ba27Row pattern recognition patch (parse/analysis).
292 | - | &patternVarNames); | c54ba27Row pattern recognition patch (parse/analysis).
293 | 4105 | pstate->p_rpr_pattern_vars = patternVarNames; | c54ba27Row pattern recognition patch (parse/analysis).
294 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
295 | - | /* | 7a69cb8Refactor transformDefineClause in row pattern recognition
296 | - | * Reject any DEFINE variable whose name does not appear in PATTERN. This | 7a69cb8Refactor transformDefineClause in row pattern recognition
297 | - | * cross-check only needs to run once, so it lives here in the caller | 7a69cb8Refactor transformDefineClause in row pattern recognition
298 | - | * rather than in the recursive validateRPRPatternVarCount(). | 7a69cb8Refactor transformDefineClause in row pattern recognition
299 | - | */ | 7a69cb8Refactor transformDefineClause in row pattern recognition
300 | 17706 | foreach_node(ResTarget, rt, windef->rpCommonSyntax->rpDefs) | 7a69cb8Refactor transformDefineClause in row pattern recognition
301 | - | { | 7a69cb8Refactor transformDefineClause in row pattern recognition
302 | - | bool found = false; | 7a69cb8Refactor transformDefineClause in row pattern recognition
303 | - |  | 7a69cb8Refactor transformDefineClause in row pattern recognition
304 | 132888 | foreach_node(String, varname, patternVarNames) | 7a69cb8Refactor transformDefineClause in row pattern recognition
305 | - | { | 7a69cb8Refactor transformDefineClause in row pattern recognition
306 | 132872 | if (strcmp(strVal(varname), rt->name) == 0) | 7a69cb8Refactor transformDefineClause in row pattern recognition
307 | - | { | 7a69cb8Refactor transformDefineClause in row pattern recognition
308 | - | found = true; | 7a69cb8Refactor transformDefineClause in row pattern recognition
309 | - | break; | 7a69cb8Refactor transformDefineClause in row pattern recognition
310 | - | } | 7a69cb8Refactor transformDefineClause in row pattern recognition
311 | - | } | 7a69cb8Refactor transformDefineClause in row pattern recognition
312 | 9528 | if (!found) | 7a69cb8Refactor transformDefineClause in row pattern recognition
313 | 9528 | ereport(ERROR, | 7a69cb8Refactor transformDefineClause in row pattern recognition
314 | - | errcode(ERRCODE_SYNTAX_ERROR), | 7a69cb8Refactor transformDefineClause in row pattern recognition
315 | - | errmsg("DEFINE variable \"%s\" is not used in PATTERN", | 7a69cb8Refactor transformDefineClause in row pattern recognition
316 | - | rt->name), | 7a69cb8Refactor transformDefineClause in row pattern recognition
317 | - | parser_errposition(pstate, rt->location)); | 7a69cb8Refactor transformDefineClause in row pattern recognition
318 | - | } | 7a69cb8Refactor transformDefineClause in row pattern recognition
319 | - |  | 7a69cb8Refactor transformDefineClause in row pattern recognition
320 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
321 | - | * Check for duplicate row pattern definition variables. The standard | c54ba27Row pattern recognition patch (parse/analysis).
322 | - | * requires that no two row pattern definition variable names shall be | c54ba27Row pattern recognition patch (parse/analysis).
323 | - | * equivalent. Report the error at the later (duplicate) definition. | 7a69cb8Refactor transformDefineClause in row pattern recognition
324 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
325 | 17670 | foreach_node(ResTarget, restarget, windef->rpCommonSyntax->rpDefs) | c54ba27Row pattern recognition patch (parse/analysis).
326 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
327 | 142135 | foreach_node(ResTarget, prior, windef->rpCommonSyntax->rpDefs) | 7a69cb8Refactor transformDefineClause in row pattern recognition
328 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
329 | 132639 | if (prior == restarget) | 7a69cb8Refactor transformDefineClause in row pattern recognition
330 | - | break; | 7a69cb8Refactor transformDefineClause in row pattern recognition
331 | 123143 | if (strcmp(prior->name, restarget->name) == 0) | 7a69cb8Refactor transformDefineClause in row pattern recognition
332 | 123143 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
333 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
334 | - | errmsg("DEFINE variable \"%s\" appears more than once", | c54ba27Row pattern recognition patch (parse/analysis).
335 | - | restarget->name), | 7a69cb8Refactor transformDefineClause in row pattern recognition
336 | - | parser_errposition(pstate, | 7a69cb8Refactor transformDefineClause in row pattern recognition
337 | - | exprLocation((Node *) restarget))); | 7a69cb8Refactor transformDefineClause in row pattern recognition
338 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
339 | - | } | 7a69cb8Refactor transformDefineClause in row pattern recognition
340 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
341 | 13421 | foreach_node(ResTarget, restarget, windef->rpCommonSyntax->rpDefs) | 7a69cb8Refactor transformDefineClause in row pattern recognition
342 | - | { | 7a69cb8Refactor transformDefineClause in row pattern recognition
343 | 9492 | TargetEntry *teDefine; | 7a69cb8Refactor transformDefineClause in row pattern recognition
344 | 9492 | Node *expr; | 7a69cb8Refactor transformDefineClause in row pattern recognition
345 | 9492 | List *vars; | 7a69cb8Refactor transformDefineClause in row pattern recognition
346 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
347 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
348 | - | * Transform the DEFINE expression and coerce it to boolean. We must | 7a69cb8Refactor transformDefineClause in row pattern recognition
349 | - | * NOT add the whole expression to the query targetlist, because it | 7a69cb8Refactor transformDefineClause in row pattern recognition
350 | - | * may contain RPRNavExpr nodes (PREV/NEXT/FIRST/LAST) that can only | 7a69cb8Refactor transformDefineClause in row pattern recognition
351 | - | * be evaluated inside the owning WindowAgg. Coercing here, before | 7a69cb8Refactor transformDefineClause in row pattern recognition
352 | - | * pull_var_clause, keeps pull_var_clause operating on the final | 7a69cb8Refactor transformDefineClause in row pattern recognition
353 | - | * expression form and surfaces a type mismatch before the targetlist | 7a69cb8Refactor transformDefineClause in row pattern recognition
354 | - | * is touched. | 7a69cb8Refactor transformDefineClause in row pattern recognition
355 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
356 | 9492 | expr = transformExpr(pstate, restarget->val, | 4cf9108Further tidy up row pattern recognition plumbing
357 | - | EXPR_KIND_RPR_DEFINE); | 4cf9108Further tidy up row pattern recognition plumbing
358 | 9352 | expr = coerce_to_boolean(pstate, expr, "DEFINE"); | 7a69cb8Refactor transformDefineClause in row pattern recognition
359 | - |  | 7a69cb8Refactor transformDefineClause in row pattern recognition
360 | - | /* Build the defineClause entry directly from the transformed expr */ | 7a69cb8Refactor transformDefineClause in row pattern recognition
361 | 9336 | teDefine = makeTargetEntry((Expr *) expr, | 7a69cb8Refactor transformDefineClause in row pattern recognition
362 | 9336 | list_length(defineClause) + 1, | 7a69cb8Refactor transformDefineClause in row pattern recognition
363 | 9336 | pstrdup(restarget->name), | 7a69cb8Refactor transformDefineClause in row pattern recognition
364 | - | true); | 7a69cb8Refactor transformDefineClause in row pattern recognition
365 | - |  | 7a69cb8Refactor transformDefineClause in row pattern recognition
366 | - | /* build transformed DEFINE clause (list of TargetEntry) */ | 7a69cb8Refactor transformDefineClause in row pattern recognition
367 | 9336 | defineClause = lappend(defineClause, teDefine); | 7a69cb8Refactor transformDefineClause in row pattern recognition
368 | - |  | 4cf9108Further tidy up row pattern recognition plumbing
369 | - | /* | 4cf9108Further tidy up row pattern recognition plumbing
370 | - | * Pull out Var nodes from the transformed expression and ensure each | 4cf9108Further tidy up row pattern recognition plumbing
371 | - | * one is present in the targetlist. This is needed so the planner | 4cf9108Further tidy up row pattern recognition plumbing
372 | - | * propagates the referenced columns through the plan tree, making | 4cf9108Further tidy up row pattern recognition plumbing
373 | - | * them available to the WindowAgg's DEFINE evaluation. | 4cf9108Further tidy up row pattern recognition plumbing
374 | - | */ | 4cf9108Further tidy up row pattern recognition plumbing
375 | 9336 | vars = pull_var_clause(expr, 0); | 4cf9108Further tidy up row pattern recognition plumbing
376 | 19373 | foreach_node(Var, var, vars) | 4cf9108Further tidy up row pattern recognition plumbing
377 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
378 | - | bool found = false; | 4cf9108Further tidy up row pattern recognition plumbing
379 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
380 | 25634 | foreach_node(TargetEntry, tle, *targetlist) | 4cf9108Further tidy up row pattern recognition plumbing
381 | - | { | 4cf9108Further tidy up row pattern recognition plumbing
382 | 23758 | if (IsA(tle->expr, Var) && | 4cf9108Further tidy up row pattern recognition plumbing
383 | 15374 | ((Var *) tle->expr)->varno == var->varno && | 4cf9108Further tidy up row pattern recognition plumbing
384 | 15338 | ((Var *) tle->expr)->varattno == var->varattno) | 4cf9108Further tidy up row pattern recognition plumbing
385 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
386 | - | found = true; | 4cf9108Further tidy up row pattern recognition plumbing
387 | - | break; | 4cf9108Further tidy up row pattern recognition plumbing
388 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
389 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
390 | 10037 | if (!found) | 4cf9108Further tidy up row pattern recognition plumbing
391 | - | { | 4cf9108Further tidy up row pattern recognition plumbing
392 | 1876 | TargetEntry *newtle; | 4cf9108Further tidy up row pattern recognition plumbing
393 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
394 | 1876 | newtle = makeTargetEntry((Expr *) copyObject(var), | 4cf9108Further tidy up row pattern recognition plumbing
395 | 3752 | list_length(*targetlist) + 1, | 4cf9108Further tidy up row pattern recognition plumbing
396 | - | NULL, | 4cf9108Further tidy up row pattern recognition plumbing
397 | - | true); | 4cf9108Further tidy up row pattern recognition plumbing
398 | 1876 | *targetlist = lappend(*targetlist, newtle); | 4cf9108Further tidy up row pattern recognition plumbing
399 | - | } | 4cf9108Further tidy up row pattern recognition plumbing
400 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
401 | 9336 | list_free(vars); | 4cf9108Further tidy up row pattern recognition plumbing
402 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
403 | 3929 | pstate->p_rpr_pattern_vars = NIL; | c54ba27Row pattern recognition patch (parse/analysis).
404 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
405 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
406 | - | * Validate DEFINE expressions: nested PREV/NEXT, column references, | c54ba27Row pattern recognition patch (parse/analysis).
407 | - | * compound flatten, volatile callees -- all in a single walk per | c54ba27Row pattern recognition patch (parse/analysis).
408 | - | * variable. | c54ba27Row pattern recognition patch (parse/analysis).
409 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
410 | 13129 | foreach_ptr(TargetEntry, te, defineClause) | c54ba27Row pattern recognition patch (parse/analysis).
411 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
412 | 9332 | DefineWalkCtx ctx; | c54ba27Row pattern recognition patch (parse/analysis).
413 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
414 | 9332 | ctx.pstate = pstate; | c54ba27Row pattern recognition patch (parse/analysis).
415 | 9332 | ctx.phase = DEFINE_PHASE_BODY; | c54ba27Row pattern recognition patch (parse/analysis).
416 | 9332 | ctx.nav_count = 0; | c54ba27Row pattern recognition patch (parse/analysis).
417 | 9332 | ctx.has_column_ref = false; | c54ba27Row pattern recognition patch (parse/analysis).
418 | 9332 | ctx.inner_kind = 0; | c54ba27Row pattern recognition patch (parse/analysis).
419 | 9332 | (void) define_walker((Node *) te->expr, &ctx); | c54ba27Row pattern recognition patch (parse/analysis).
420 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
421 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
422 | - | /* mark column origins */ | c54ba27Row pattern recognition patch (parse/analysis).
423 | 3797 | markTargetListOrigins(pstate, defineClause); | c54ba27Row pattern recognition patch (parse/analysis).
424 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
425 | - | /* mark all nodes in the DEFINE clause tree with collation information */ | c54ba27Row pattern recognition patch (parse/analysis).
426 | 3797 | assign_expr_collations(pstate, (Node *) defineClause); | c54ba27Row pattern recognition patch (parse/analysis).
427 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
428 | 3797 | return defineClause; | c54ba27Row pattern recognition patch (parse/analysis).
429 | - | } | c54ba27Row pattern recognition patch (parse/analysis).

define_walker() lines 476-651
Modified Lines Coverage: 67/67 lines (100.0%)

Line | Hits | Source | Commit
--- | --- | --- | ---
476 | 37281 | define_walker(Node *node, void *context) | c54ba27Row pattern recognition patch (parse/analysis).
477 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
478 | 37281 | DefineWalkCtx *ctx = (DefineWalkCtx *) context; | c54ba27Row pattern recognition patch (parse/analysis).
479 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
480 | 37281 | if (node == NULL) | c54ba27Row pattern recognition patch (parse/analysis).
481 | - | return false; | c54ba27Row pattern recognition patch (parse/analysis).
482 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
483 | - | /* Var sighting feeds the column-ref rule for the enclosing nav scope. */ | c54ba27Row pattern recognition patch (parse/analysis).
484 | 37277 | if (IsA(node, Var) && | c54ba27Row pattern recognition patch (parse/analysis).
485 | 10029 | (ctx->phase == DEFINE_PHASE_NAV_ARG || | c54ba27Row pattern recognition patch (parse/analysis).
486 | - | ctx->phase == DEFINE_PHASE_NAV_OFFSET)) | c54ba27Row pattern recognition patch (parse/analysis).
487 | 1250 | ctx->has_column_ref = true; | c54ba27Row pattern recognition patch (parse/analysis).
488 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
489 | 37277 | if (IsA(node, RPRNavExpr)) | c54ba27Row pattern recognition patch (parse/analysis).
490 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
491 | 1544 | RPRNavExpr *nav = (RPRNavExpr *) node; | c54ba27Row pattern recognition patch (parse/analysis).
492 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
493 | 1544 | if (ctx->phase == DEFINE_PHASE_NAV_ARG) | c54ba27Row pattern recognition patch (parse/analysis).
494 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
495 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
496 | - | * Nested nav inside an outer nav.arg: record for the outer's | c54ba27Row pattern recognition patch (parse/analysis).
497 | - | * compound / nesting decision, then keep recursing so deeper Vars | c54ba27Row pattern recognition patch (parse/analysis).
498 | - | * and volatile callees are still observed. | c54ba27Row pattern recognition patch (parse/analysis).
499 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
500 | 246 | if (ctx->nav_count == 0) | c54ba27Row pattern recognition patch (parse/analysis).
501 | 234 | ctx->inner_kind = nav->kind; | c54ba27Row pattern recognition patch (parse/analysis).
502 | 246 | ctx->nav_count++; | c54ba27Row pattern recognition patch (parse/analysis).
503 | 246 | return expression_tree_walker(node, define_walker, ctx); | c54ba27Row pattern recognition patch (parse/analysis).
504 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
505 | 1298 | else if (ctx->phase == DEFINE_PHASE_NAV_OFFSET) | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
506 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
507 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
508 | - | * A navigation offset must be a run-time constant, so it cannot | 7f135d9Recognize row pattern navigation operations by name in DEFINE
509 | - | * contain a navigation operation. | 7f135d9Recognize row pattern navigation operations by name in DEFINE
510 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
511 | 32 | ereport(ERROR, | 7f135d9Recognize row pattern navigation operations by name in DEFINE
512 | - | errcode(ERRCODE_SYNTAX_ERROR), | 7f135d9Recognize row pattern navigation operations by name in DEFINE
513 | - | errmsg("row pattern navigation offset cannot contain a row pattern navigation operation"), | 7f135d9Recognize row pattern navigation operations by name in DEFINE
514 | - | errdetail("A navigation offset must be a run-time constant."), | 7f135d9Recognize row pattern navigation operations by name in DEFINE
515 | - | parser_errposition(ctx->pstate, nav->location)); | 7f135d9Recognize row pattern navigation operations by name in DEFINE
516 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
517 | - | else | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
518 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
519 | - | /* | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
520 | - | * PHASE_BODY: this is an outer nav at top level. Walk arg first | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
521 | - | * to collect nesting / column-ref state, then validate and (for | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
522 | - | * compound forms) flatten, then walk offset(s). | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
523 | - | */ | f3dda49Replace a bare block with an else in the RPR DEFINE clause walker
524 | 1266 | DefineWalkCtx saved = *ctx; | c54ba27Row pattern recognition patch (parse/analysis).
525 | 1266 | bool outer_phys = (nav->kind == RPR_NAV_PREV || | c54ba27Row pattern recognition patch (parse/analysis).
526 | - | nav->kind == RPR_NAV_NEXT); | c54ba27Row pattern recognition patch (parse/analysis).
527 | 1266 | bool flattened = false; | c54ba27Row pattern recognition patch (parse/analysis).
528 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
529 | 1266 | ctx->phase = DEFINE_PHASE_NAV_ARG; | c54ba27Row pattern recognition patch (parse/analysis).
530 | 1266 | ctx->nav_count = 0; | c54ba27Row pattern recognition patch (parse/analysis).
531 | 1266 | ctx->has_column_ref = false; | c54ba27Row pattern recognition patch (parse/analysis).
532 | 1266 | ctx->inner_kind = 0; | c54ba27Row pattern recognition patch (parse/analysis).
533 | 1266 | (void) define_walker((Node *) nav->arg, ctx); | c54ba27Row pattern recognition patch (parse/analysis).
534 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
535 | 1266 | if (ctx->nav_count > 0) | c54ba27Row pattern recognition patch (parse/analysis).
536 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
537 | 234 | bool inner_phys = (ctx->inner_kind == RPR_NAV_PREV || | c54ba27Row pattern recognition patch (parse/analysis).
538 | - | ctx->inner_kind == RPR_NAV_NEXT); | c54ba27Row pattern recognition patch (parse/analysis).
539 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
540 | 234 | if (outer_phys && !inner_phys) | c54ba27Row pattern recognition patch (parse/analysis).
541 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
542 | 202 | RPRNavExpr *inner; | c54ba27Row pattern recognition patch (parse/analysis).
543 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
544 | - | /* Reject triple-or-deeper nesting */ | c54ba27Row pattern recognition patch (parse/analysis).
545 | 202 | if (ctx->nav_count > 1) | c54ba27Row pattern recognition patch (parse/analysis).
546 | 8 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
547 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
548 | - | errmsg("cannot nest row pattern navigation more than two levels deep"), | c54ba27Row pattern recognition patch (parse/analysis).
549 | - | errhint("Only PREV(FIRST()), PREV(LAST()), NEXT(FIRST()), and NEXT(LAST()) compound forms are allowed."), | c54ba27Row pattern recognition patch (parse/analysis).
550 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
551 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
552 | 194 | if (!IsA(nav->arg, RPRNavExpr)) | c54ba27Row pattern recognition patch (parse/analysis).
553 | 4 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
554 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
555 | - | errmsg("row pattern navigation operation must be a direct argument of the outer navigation"), | c54ba27Row pattern recognition patch (parse/analysis).
556 | - | errhint("Only PREV(FIRST()), PREV(LAST()), NEXT(FIRST()), and NEXT(LAST()) compound forms are allowed."), | c54ba27Row pattern recognition patch (parse/analysis).
557 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
558 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
559 | 190 | inner = (RPRNavExpr *) nav->arg; | c54ba27Row pattern recognition patch (parse/analysis).
560 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
561 | 190 | if (nav->kind == RPR_NAV_PREV && inner->kind == RPR_NAV_FIRST) | c54ba27Row pattern recognition patch (parse/analysis).
562 | 95 | nav->kind = RPR_NAV_PREV_FIRST; | c54ba27Row pattern recognition patch (parse/analysis).
563 | 95 | else if (nav->kind == RPR_NAV_PREV && inner->kind == RPR_NAV_LAST) | c54ba27Row pattern recognition patch (parse/analysis).
564 | 33 | nav->kind = RPR_NAV_PREV_LAST; | c54ba27Row pattern recognition patch (parse/analysis).
565 | 62 | else if (nav->kind == RPR_NAV_NEXT && inner->kind == RPR_NAV_FIRST) | c54ba27Row pattern recognition patch (parse/analysis).
566 | 29 | nav->kind = RPR_NAV_NEXT_FIRST; | c54ba27Row pattern recognition patch (parse/analysis).
567 | 33 | else if (nav->kind == RPR_NAV_NEXT && inner->kind == RPR_NAV_LAST) | c54ba27Row pattern recognition patch (parse/analysis).
568 | 33 | nav->kind = RPR_NAV_NEXT_LAST; | c54ba27Row pattern recognition patch (parse/analysis).
569 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
570 | 190 | nav->compound_offset_arg = nav->offset_arg; | c54ba27Row pattern recognition patch (parse/analysis).
571 | 190 | nav->offset_arg = inner->offset_arg; | c54ba27Row pattern recognition patch (parse/analysis).
572 | 190 | nav->arg = inner->arg; | c54ba27Row pattern recognition patch (parse/analysis).
573 | 190 | flattened = true; | c54ba27Row pattern recognition patch (parse/analysis).
574 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
575 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
576 | - | * The flattened argument must include a column reference, | c54ba27Row pattern recognition patch (parse/analysis).
577 | - | * just like the simple-nav case below. | c54ba27Row pattern recognition patch (parse/analysis).
578 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
579 | 190 | if (!ctx->has_column_ref) | c54ba27Row pattern recognition patch (parse/analysis).
580 | 20 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
581 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
582 | - | errmsg("argument of row pattern navigation operation must include at least one column reference"), | c54ba27Row pattern recognition patch (parse/analysis).
583 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
584 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
585 | 32 | else if (!outer_phys && inner_phys) | c54ba27Row pattern recognition patch (parse/analysis).
586 | 8 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
587 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
588 | - | errmsg("FIRST and LAST cannot contain PREV or NEXT"), | c54ba27Row pattern recognition patch (parse/analysis).
589 | - | errhint("Only PREV(FIRST()), PREV(LAST()), NEXT(FIRST()), and NEXT(LAST()) compound forms are allowed."), | c54ba27Row pattern recognition patch (parse/analysis).
590 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
591 | 24 | else if (outer_phys && inner_phys) | c54ba27Row pattern recognition patch (parse/analysis).
592 | 20 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
593 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
594 | - | errmsg("PREV and NEXT cannot contain PREV or NEXT"), | c54ba27Row pattern recognition patch (parse/analysis).
595 | - | errhint("Only PREV(FIRST()), PREV(LAST()), NEXT(FIRST()), and NEXT(LAST()) compound forms are allowed."), | c54ba27Row pattern recognition patch (parse/analysis).
596 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
597 | - | else | c54ba27Row pattern recognition patch (parse/analysis).
598 | 4 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
599 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
600 | - | errmsg("FIRST and LAST cannot contain FIRST or LAST"), | c54ba27Row pattern recognition patch (parse/analysis).
601 | - | errhint("Only PREV(FIRST()), PREV(LAST()), NEXT(FIRST()), and NEXT(LAST()) compound forms are allowed."), | c54ba27Row pattern recognition patch (parse/analysis).
602 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
603 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
604 | 1032 | else if (!ctx->has_column_ref) | c54ba27Row pattern recognition patch (parse/analysis).
605 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
606 | 24 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
607 | - | errcode(ERRCODE_SYNTAX_ERROR), | c54ba27Row pattern recognition patch (parse/analysis).
608 | - | errmsg("argument of row pattern navigation operation must include at least one column reference"), | c54ba27Row pattern recognition patch (parse/analysis).
609 | - | parser_errposition(ctx->pstate, nav->location)); | c54ba27Row pattern recognition patch (parse/analysis).
610 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
611 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
612 | - | /* | c54ba27Row pattern recognition patch (parse/analysis).
613 | - | * Walk offset arg(s) in PHASE_NAV_OFFSET to enforce the | c54ba27Row pattern recognition patch (parse/analysis).
614 | - | * constant-offset rule. For compound forms, both the inner | c54ba27Row pattern recognition patch (parse/analysis).
615 | - | * (post-flatten nav->offset_arg) and outer (compound_offset_arg) | c54ba27Row pattern recognition patch (parse/analysis).
616 | - | * offsets must be constants; the inner's column-ref status was | c54ba27Row pattern recognition patch (parse/analysis).
617 | - | * not separately tracked during the PHASE_NAV_ARG walk (which | c54ba27Row pattern recognition patch (parse/analysis).
618 | - | * only checks that nav.arg as a whole has at least one Var), so | c54ba27Row pattern recognition patch (parse/analysis).
619 | - | * it is re-walked here to catch column references the inner | c54ba27Row pattern recognition patch (parse/analysis).
620 | - | * offset would have leaked. | c54ba27Row pattern recognition patch (parse/analysis).
621 | - | */ | c54ba27Row pattern recognition patch (parse/analysis).
622 | 1178 | ctx->phase = DEFINE_PHASE_NAV_OFFSET; | c54ba27Row pattern recognition patch (parse/analysis).
623 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
624 | 1178 | if (nav->offset_arg != NULL) | c54ba27Row pattern recognition patch (parse/analysis).
625 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
626 | 294 | ctx->has_column_ref = false; | c54ba27Row pattern recognition patch (parse/analysis).
627 | 294 | (void) define_walker((Node *) nav->offset_arg, ctx); | c54ba27Row pattern recognition patch (parse/analysis).
628 | 266 | if (ctx->has_column_ref) | c54ba27Row pattern recognition patch (parse/analysis).
629 | 8 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
630 | - | errcode(ERRCODE_FEATURE_NOT_SUPPORTED), | c54ba27Row pattern recognition patch (parse/analysis).
631 | - | errmsg("row pattern navigation offset must be a run-time constant"), | c54ba27Row pattern recognition patch (parse/analysis).
632 | - | parser_errposition(ctx->pstate, exprLocation((Node *) nav->offset_arg))); | c54ba27Row pattern recognition patch (parse/analysis).
633 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
634 | 1142 | if (flattened && nav->compound_offset_arg != NULL) | c54ba27Row pattern recognition patch (parse/analysis).
635 | - | { | c54ba27Row pattern recognition patch (parse/analysis).
636 | 153 | ctx->has_column_ref = false; | c54ba27Row pattern recognition patch (parse/analysis).
637 | 153 | (void) define_walker((Node *) nav->compound_offset_arg, ctx); | c54ba27Row pattern recognition patch (parse/analysis).
638 | 149 | if (ctx->has_column_ref) | c54ba27Row pattern recognition patch (parse/analysis).
639 | 4 | ereport(ERROR, | c54ba27Row pattern recognition patch (parse/analysis).
640 | - | errcode(ERRCODE_FEATURE_NOT_SUPPORTED), | c54ba27Row pattern recognition patch (parse/analysis).
641 | - | errmsg("row pattern navigation offset must be a run-time constant"), | c54ba27Row pattern recognition patch (parse/analysis).
642 | - | parser_errposition(ctx->pstate, exprLocation((Node *) nav->compound_offset_arg))); | c54ba27Row pattern recognition patch (parse/analysis).
643 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
644 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
645 | 1134 | *ctx = saved; | c54ba27Row pattern recognition patch (parse/analysis).
646 | 1134 | return false; | c54ba27Row pattern recognition patch (parse/analysis).
647 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
648 | - | } | c54ba27Row pattern recognition patch (parse/analysis).
649 | - |  | c54ba27Row pattern recognition patch (parse/analysis).
650 | 35733 | return expression_tree_walker(node, define_walker, ctx); | c54ba27Row pattern recognition patch (parse/analysis).
651 | - | } | c54ba27Row pattern recognition patch (parse/analysis).