← Back to Overview

src/backend/optimizer/plan/rpr.c

Coverage: 669/679 lines (98.5%)
Total Lines
679
modified
Covered
669
98.5%
Uncovered
10
1.5%
키보드 네비게이션
rprPatternEqual() lines 105-130
Modified Lines Coverage: 11/13 lines (84.6%)
LineHitsSourceCommit
105 323 rprPatternEqual(RPRPatternNode *a, RPRPatternNode *b) ba2f29fRow pattern recognition patch (planner).
106 - { ba2f29fRow pattern recognition patch (planner).
107 - /* Pattern nodes in children lists must never be NULL */ ba2f29fRow pattern recognition patch (planner).
108 323 Assert(a != NULL && b != NULL); ba2f29fRow pattern recognition patch (planner).
109 - ba2f29fRow pattern recognition patch (planner).
110 - /* Must have same node type and quantifiers */ ba2f29fRow pattern recognition patch (planner).
111 323 if (a->nodeType != b->nodeType) ba2f29fRow pattern recognition patch (planner).
112 27 return false; ba2f29fRow pattern recognition patch (planner).
113 296 if (a->min != b->min || a->max != b->max) ba2f29fRow pattern recognition patch (planner).
114 8 return false; ba2f29fRow pattern recognition patch (planner).
115 288 if (a->reluctant != b->reluctant) ba2f29fRow pattern recognition patch (planner).
116 0 return false; ba2f29fRow pattern recognition patch (planner).
117 - ba2f29fRow pattern recognition patch (planner).
118 288 switch (a->nodeType) ba2f29fRow pattern recognition patch (planner).
119 - { ba2f29fRow pattern recognition patch (planner).
120 - case RPR_PATTERN_VAR: ba2f29fRow pattern recognition patch (planner).
121 255 return strcmp(a->varName, b->varName) == 0; ba2f29fRow pattern recognition patch (planner).
122 - ba2f29fRow pattern recognition patch (planner).
123 - case RPR_PATTERN_SEQ: ba2f29fRow pattern recognition patch (planner).
124 - case RPR_PATTERN_ALT: ba2f29fRow pattern recognition patch (planner).
125 - case RPR_PATTERN_GROUP: ba2f29fRow pattern recognition patch (planner).
126 33 return rprPatternChildrenEqual(a->children, b->children); ba2f29fRow pattern recognition patch (planner).
127 - } ba2f29fRow pattern recognition patch (planner).
128 - ba2f29fRow pattern recognition patch (planner).
129 0 return false; /* keep compiler quiet */ ba2f29fRow pattern recognition patch (planner).
130 323 } ba2f29fRow pattern recognition patch (planner).
rprPatternChildrenEqual() lines 139-155
Modified Lines Coverage: 11/11 lines (100.0%)
LineHitsSourceCommit
139 108 rprPatternChildrenEqual(List *a, List *b) ba2f29fRow pattern recognition patch (planner).
140 - { ba2f29fRow pattern recognition patch (planner).
141 108 ListCell *lca, ba2f29fRow pattern recognition patch (planner).
142 - *lcb; ba2f29fRow pattern recognition patch (planner).
143 - ba2f29fRow pattern recognition patch (planner).
144 108 if (list_length(a) != list_length(b)) ba2f29fRow pattern recognition patch (planner).
145 20 return false; ba2f29fRow pattern recognition patch (planner).
146 - ba2f29fRow pattern recognition patch (planner).
147 226 forboth(lca, a, lcb, b) ba2f29fRow pattern recognition patch (planner).
148 - { ba2f29fRow pattern recognition patch (planner).
149 276 if (!rprPatternEqual((RPRPatternNode *) lfirst(lca), ba2f29fRow pattern recognition patch (planner).
150 138 (RPRPatternNode *) lfirst(lcb))) ba2f29fRow pattern recognition patch (planner).
151 30 return false; ba2f29fRow pattern recognition patch (planner).
152 108 } ba2f29fRow pattern recognition patch (planner).
153 - ba2f29fRow pattern recognition patch (planner).
154 58 return true; ba2f29fRow pattern recognition patch (planner).
155 108 } ba2f29fRow pattern recognition patch (planner).
tryUnwrapSingleChild() lines 170-176
Modified Lines Coverage: 5/5 lines (100.0%)
LineHitsSourceCommit
170 479 tryUnwrapSingleChild(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
171 - { ba2f29fRow pattern recognition patch (planner).
172 479 if (list_length(pattern->children) == 1) ba2f29fRow pattern recognition patch (planner).
173 35 return (RPRPatternNode *) linitial(pattern->children); ba2f29fRow pattern recognition patch (planner).
174 - ba2f29fRow pattern recognition patch (planner).
175 444 return pattern; ba2f29fRow pattern recognition patch (planner).
176 479 } ba2f29fRow pattern recognition patch (planner).
flattenSeqChildren() lines 189-215
Modified Lines Coverage: 15/15 lines (100.0%)
LineHitsSourceCommit
189 350 flattenSeqChildren(List *children) ba2f29fRow pattern recognition patch (planner).
190 - { ba2f29fRow pattern recognition patch (planner).
191 350 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
192 350 List *newChildren = NIL; ba2f29fRow pattern recognition patch (planner).
193 - ba2f29fRow pattern recognition patch (planner).
194 1508 foreach(lc, children) ba2f29fRow pattern recognition patch (planner).
195 - { ba2f29fRow pattern recognition patch (planner).
196 1158 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
197 1158 RPRPatternNode *opt = optimizeRPRPattern(child); ba2f29fRow pattern recognition patch (planner).
198 - ba2f29fRow pattern recognition patch (planner).
199 - /* GROUP{1,1} should have been unwrapped by optimizeGroupPattern */ ba2f29fRow pattern recognition patch (planner).
200 1158 Assert(!(opt->nodeType == RPR_PATTERN_GROUP && ba2f29fRow pattern recognition patch (planner).
201 - opt->min == 1 && opt->max == 1 && opt->reluctant < 0)); ba2f29fRow pattern recognition patch (planner).
202 - ba2f29fRow pattern recognition patch (planner).
203 1158 if (opt->nodeType == RPR_PATTERN_SEQ) ba2f29fRow pattern recognition patch (planner).
204 - { ba2f29fRow pattern recognition patch (planner).
205 24 newChildren = list_concat(newChildren, ba2f29fRow pattern recognition patch (planner).
206 12 list_copy(opt->children)); ba2f29fRow pattern recognition patch (planner).
207 12 } ba2f29fRow pattern recognition patch (planner).
208 - else ba2f29fRow pattern recognition patch (planner).
209 - { ba2f29fRow pattern recognition patch (planner).
210 1146 newChildren = lappend(newChildren, opt); ba2f29fRow pattern recognition patch (planner).
211 - } ba2f29fRow pattern recognition patch (planner).
212 1158 } ba2f29fRow pattern recognition patch (planner).
213 - ba2f29fRow pattern recognition patch (planner).
214 700 return newChildren; ba2f29fRow pattern recognition patch (planner).
215 350 } ba2f29fRow pattern recognition patch (planner).
mergeConsecutiveVars() lines 227-289
Modified Lines Coverage: 33/33 lines (100.0%)
LineHitsSourceCommit
227 350 mergeConsecutiveVars(List *children) ba2f29fRow pattern recognition patch (planner).
228 - { ba2f29fRow pattern recognition patch (planner).
229 350 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
230 350 List *mergedChildren = NIL; ba2f29fRow pattern recognition patch (planner).
231 350 RPRPatternNode *prev = NULL; ba2f29fRow pattern recognition patch (planner).
232 - ba2f29fRow pattern recognition patch (planner).
233 1520 foreach(lc, children) ba2f29fRow pattern recognition patch (planner).
234 - { ba2f29fRow pattern recognition patch (planner).
235 1170 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
236 - ba2f29fRow pattern recognition patch (planner).
237 1170 if (child->nodeType == RPR_PATTERN_VAR && child->reluctant < 0) ba2f29fRow pattern recognition patch (planner).
238 - { ba2f29fRow pattern recognition patch (planner).
239 - /* ---------------------- ba2f29fRow pattern recognition patch (planner).
240 - * Can merge consecutive VAR nodes if: ba2f29fRow pattern recognition patch (planner).
241 - * 1. Same variable name ba2f29fRow pattern recognition patch (planner).
242 - * 2. No min overflow: prev->min + child->min <= INF ba2f29fRow pattern recognition patch (planner).
243 - * 3. No max overflow: prev->max + child->max <= INF (or either is INF) ba2f29fRow pattern recognition patch (planner).
244 - */ ba2f29fRow pattern recognition patch (planner).
245 1059 if (prev != NULL && ba2f29fRow pattern recognition patch (planner).
246 712 strcmp(prev->varName, child->varName) == 0 && ba2f29fRow pattern recognition patch (planner).
247 22 prev->min <= RPR_QUANTITY_INF - child->min && ba2f29fRow pattern recognition patch (planner).
248 22 (prev->max <= RPR_QUANTITY_INF - child->max || ba2f29fRow pattern recognition patch (planner).
249 9 prev->max == RPR_QUANTITY_INF || ba2f29fRow pattern recognition patch (planner).
250 3 child->max == RPR_QUANTITY_INF)) ba2f29fRow pattern recognition patch (planner).
251 - { ba2f29fRow pattern recognition patch (planner).
252 - /* ba2f29fRow pattern recognition patch (planner).
253 - * Merge: accumulate min/max into prev. prev is guaranteed to ba2f29fRow pattern recognition patch (planner).
254 - * be a non-reluctant VAR by the outer condition. ba2f29fRow pattern recognition patch (planner).
255 - */ ba2f29fRow pattern recognition patch (planner).
256 22 Assert(prev->nodeType == RPR_PATTERN_VAR && prev->reluctant < 0); ba2f29fRow pattern recognition patch (planner).
257 - ba2f29fRow pattern recognition patch (planner).
258 22 prev->min += child->min; ba2f29fRow pattern recognition patch (planner).
259 - ba2f29fRow pattern recognition patch (planner).
260 22 if (prev->max == RPR_QUANTITY_INF || ba2f29fRow pattern recognition patch (planner).
261 16 child->max == RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
262 9 prev->max = RPR_QUANTITY_INF; ba2f29fRow pattern recognition patch (planner).
263 - else ba2f29fRow pattern recognition patch (planner).
264 13 prev->max += child->max; ba2f29fRow pattern recognition patch (planner).
265 22 } ba2f29fRow pattern recognition patch (planner).
266 - else ba2f29fRow pattern recognition patch (planner).
267 - { ba2f29fRow pattern recognition patch (planner).
268 - /* Flush previous and start new */ ba2f29fRow pattern recognition patch (planner).
269 1034 if (prev != NULL) ba2f29fRow pattern recognition patch (planner).
270 690 mergedChildren = lappend(mergedChildren, prev); ba2f29fRow pattern recognition patch (planner).
271 1034 prev = child; ba2f29fRow pattern recognition patch (planner).
272 - } ba2f29fRow pattern recognition patch (planner).
273 1056 } ba2f29fRow pattern recognition patch (planner).
274 - else ba2f29fRow pattern recognition patch (planner).
275 - { ba2f29fRow pattern recognition patch (planner).
276 - /* Non-mergeable - flush previous */ ba2f29fRow pattern recognition patch (planner).
277 114 if (prev != NULL) ba2f29fRow pattern recognition patch (planner).
278 32 mergedChildren = lappend(mergedChildren, prev); ba2f29fRow pattern recognition patch (planner).
279 114 mergedChildren = lappend(mergedChildren, child); ba2f29fRow pattern recognition patch (planner).
280 114 prev = NULL; ba2f29fRow pattern recognition patch (planner).
281 - } ba2f29fRow pattern recognition patch (planner).
282 1170 } ba2f29fRow pattern recognition patch (planner).
283 - ba2f29fRow pattern recognition patch (planner).
284 - /* Flush remaining */ ba2f29fRow pattern recognition patch (planner).
285 350 if (prev != NULL) ba2f29fRow pattern recognition patch (planner).
286 312 mergedChildren = lappend(mergedChildren, prev); ba2f29fRow pattern recognition patch (planner).
287 - ba2f29fRow pattern recognition patch (planner).
288 700 return mergedChildren; ba2f29fRow pattern recognition patch (planner).
289 350 } ba2f29fRow pattern recognition patch (planner).
mergeConsecutiveGroups() lines 301-363
Modified Lines Coverage: 33/33 lines (100.0%)
LineHitsSourceCommit
301 350 mergeConsecutiveGroups(List *children) ba2f29fRow pattern recognition patch (planner).
302 - { ba2f29fRow pattern recognition patch (planner).
303 350 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
304 350 List *mergedChildren = NIL; ba2f29fRow pattern recognition patch (planner).
305 350 RPRPatternNode *prev = NULL; ba2f29fRow pattern recognition patch (planner).
306 - ba2f29fRow pattern recognition patch (planner).
307 1498 foreach(lc, children) ba2f29fRow pattern recognition patch (planner).
308 - { ba2f29fRow pattern recognition patch (planner).
309 1148 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
310 - ba2f29fRow pattern recognition patch (planner).
311 1148 if (child->nodeType == RPR_PATTERN_GROUP && child->reluctant < 0) ba2f29fRow pattern recognition patch (planner).
312 - { ba2f29fRow pattern recognition patch (planner).
313 - /* ---------------------- ba2f29fRow pattern recognition patch (planner).
314 - * Can merge consecutive GROUP nodes if: ba2f29fRow pattern recognition patch (planner).
315 - * 1. Identical children ba2f29fRow pattern recognition patch (planner).
316 - * 2. No min overflow: prev->min + child->min <= INF ba2f29fRow pattern recognition patch (planner).
317 - * 3. No max overflow: prev->max + child->max <= INF (or either is INF) ba2f29fRow pattern recognition patch (planner).
318 - */ ba2f29fRow pattern recognition patch (planner).
319 54 if (prev != NULL && ba2f29fRow pattern recognition patch (planner).
320 8 rprPatternChildrenEqual(prev->children, child->children) && ba2f29fRow pattern recognition patch (planner).
321 6 prev->min <= RPR_QUANTITY_INF - child->min && ba2f29fRow pattern recognition patch (planner).
322 6 (prev->max <= RPR_QUANTITY_INF - child->max || ba2f29fRow pattern recognition patch (planner).
323 4 prev->max == RPR_QUANTITY_INF || ba2f29fRow pattern recognition patch (planner).
324 1 child->max == RPR_QUANTITY_INF)) ba2f29fRow pattern recognition patch (planner).
325 - { ba2f29fRow pattern recognition patch (planner).
326 - /* ba2f29fRow pattern recognition patch (planner).
327 - * Merge: accumulate min/max into prev. prev is guaranteed to ba2f29fRow pattern recognition patch (planner).
328 - * be a non-reluctant GROUP by the outer condition. ba2f29fRow pattern recognition patch (planner).
329 - */ ba2f29fRow pattern recognition patch (planner).
330 6 Assert(prev->nodeType == RPR_PATTERN_GROUP && prev->reluctant < 0); ba2f29fRow pattern recognition patch (planner).
331 - ba2f29fRow pattern recognition patch (planner).
332 6 prev->min += child->min; ba2f29fRow pattern recognition patch (planner).
333 - ba2f29fRow pattern recognition patch (planner).
334 6 if (prev->max == RPR_QUANTITY_INF || ba2f29fRow pattern recognition patch (planner).
335 3 child->max == RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
336 4 prev->max = RPR_QUANTITY_INF; ba2f29fRow pattern recognition patch (planner).
337 - else ba2f29fRow pattern recognition patch (planner).
338 2 prev->max += child->max; ba2f29fRow pattern recognition patch (planner).
339 6 } ba2f29fRow pattern recognition patch (planner).
340 - else ba2f29fRow pattern recognition patch (planner).
341 - { ba2f29fRow pattern recognition patch (planner).
342 - /* Flush previous and start new */ ba2f29fRow pattern recognition patch (planner).
343 47 if (prev != NULL) ba2f29fRow pattern recognition patch (planner).
344 2 mergedChildren = lappend(mergedChildren, prev); ba2f29fRow pattern recognition patch (planner).
345 47 prev = child; ba2f29fRow pattern recognition patch (planner).
346 - } ba2f29fRow pattern recognition patch (planner).
347 53 } ba2f29fRow pattern recognition patch (planner).
348 - else ba2f29fRow pattern recognition patch (planner).
349 - { ba2f29fRow pattern recognition patch (planner).
350 - /* Non-mergeable - flush previous */ ba2f29fRow pattern recognition patch (planner).
351 1095 if (prev != NULL) ba2f29fRow pattern recognition patch (planner).
352 23 mergedChildren = lappend(mergedChildren, prev); ba2f29fRow pattern recognition patch (planner).
353 1095 mergedChildren = lappend(mergedChildren, child); ba2f29fRow pattern recognition patch (planner).
354 1095 prev = NULL; ba2f29fRow pattern recognition patch (planner).
355 - } ba2f29fRow pattern recognition patch (planner).
356 1148 } ba2f29fRow pattern recognition patch (planner).
357 - ba2f29fRow pattern recognition patch (planner).
358 - /* Flush remaining */ ba2f29fRow pattern recognition patch (planner).
359 350 if (prev != NULL) ba2f29fRow pattern recognition patch (planner).
360 22 mergedChildren = lappend(mergedChildren, prev); ba2f29fRow pattern recognition patch (planner).
361 - ba2f29fRow pattern recognition patch (planner).
362 700 return mergedChildren; ba2f29fRow pattern recognition patch (planner).
363 350 } ba2f29fRow pattern recognition patch (planner).
mergeConsecutiveAlts() lines 377-467
Modified Lines Coverage: 60/60 lines (100.0%)
LineHitsSourceCommit
377 350 mergeConsecutiveAlts(List *children) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
378 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
379 350 ListCell *lc; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
380 350 List *mergedChildren = NIL; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
381 350 RPRPatternNode *prev = NULL; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
382 350 int count = 0; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
383 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
384 1492 foreach(lc, children) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
385 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
386 1142 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
387 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
388 1142 if (child->nodeType == RPR_PATTERN_ALT && child->reluctant < 0) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
389 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
390 61 if (prev != NULL && 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
391 24 rprPatternChildrenEqual(prev->children, child->children)) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
392 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
393 - /* Same ALT as prev - accumulate */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
394 16 count++; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
395 16 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
396 - else 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
397 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
398 - /* Different ALT or first ALT - flush previous */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
399 45 if (prev != NULL) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
400 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
401 8 if (count > 1) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
402 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
403 - /* Wrap in GROUP{count,count}(ALT) */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
404 1 RPRPatternNode *group = makeNode(RPRPatternNode); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
405 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
406 1 group->nodeType = RPR_PATTERN_GROUP; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
407 1 group->min = count; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
408 1 group->max = count; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
409 1 group->reluctant = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
410 1 group->location = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
411 1 group->children = list_make1(prev); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
412 1 mergedChildren = lappend(mergedChildren, group); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
413 1 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
414 - else 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
415 7 mergedChildren = lappend(mergedChildren, prev); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
416 8 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
417 45 prev = child; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
418 45 count = 1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
419 - } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
420 61 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
421 - else 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
422 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
423 - /* Non-ALT - flush previous */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
424 1081 if (prev != NULL) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
425 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
426 21 if (count > 1) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
427 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
428 1 RPRPatternNode *group = makeNode(RPRPatternNode); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
429 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
430 1 group->nodeType = RPR_PATTERN_GROUP; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
431 1 group->min = count; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
432 1 group->max = count; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
433 1 group->reluctant = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
434 1 group->location = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
435 1 group->children = list_make1(prev); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
436 1 mergedChildren = lappend(mergedChildren, group); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
437 1 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
438 - else 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
439 20 mergedChildren = lappend(mergedChildren, prev); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
440 21 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
441 1081 mergedChildren = lappend(mergedChildren, child); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
442 1081 prev = NULL; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
443 1081 count = 0; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
444 - } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
445 1142 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
446 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
447 - /* Flush remaining */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
448 350 if (prev != NULL) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
449 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
450 16 if (count > 1) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
451 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
452 2 RPRPatternNode *group = makeNode(RPRPatternNode); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
453 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
454 2 group->nodeType = RPR_PATTERN_GROUP; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
455 2 group->min = count; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
456 2 group->max = count; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
457 2 group->reluctant = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
458 2 group->location = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
459 2 group->children = list_make1(prev); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
460 2 mergedChildren = lappend(mergedChildren, group); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
461 2 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
462 - else 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
463 14 mergedChildren = lappend(mergedChildren, prev); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
464 16 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
465 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
466 700 return mergedChildren; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
467 350 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
mergeGroupPrefixSuffix() lines 479-625
Modified Lines Coverage: 68/68 lines (100.0%)
LineHitsSourceCommit
479 350 mergeGroupPrefixSuffix(List *children) ba2f29fRow pattern recognition patch (planner).
480 - { ba2f29fRow pattern recognition patch (planner).
481 350 List *result = NIL; ba2f29fRow pattern recognition patch (planner).
482 350 int numChildren = list_length(children); ba2f29fRow pattern recognition patch (planner).
483 350 int i; ba2f29fRow pattern recognition patch (planner).
484 350 int skipUntil = -1; /* skip suffix elements already absorbed */ ba2f29fRow pattern recognition patch (planner).
485 - ba2f29fRow pattern recognition patch (planner).
486 1456 for (i = 0; i < numChildren; i++) ba2f29fRow pattern recognition patch (planner).
487 - { ba2f29fRow pattern recognition patch (planner).
488 1106 RPRPatternNode *child = (RPRPatternNode *) list_nth(children, i); ba2f29fRow pattern recognition patch (planner).
489 - ba2f29fRow pattern recognition patch (planner).
490 - /* ba2f29fRow pattern recognition patch (planner).
491 - * The suffix absorption logic below adjusts i to skip absorbed ba2f29fRow pattern recognition patch (planner).
492 - * elements, ensuring we never revisit them. Verify this invariant. ba2f29fRow pattern recognition patch (planner).
493 - */ ba2f29fRow pattern recognition patch (planner).
494 1106 Assert(i >= skipUntil); ba2f29fRow pattern recognition patch (planner).
495 - ba2f29fRow pattern recognition patch (planner).
496 - /* ba2f29fRow pattern recognition patch (planner).
497 - * If this is a GROUP, see if preceding/following elements match its ba2f29fRow pattern recognition patch (planner).
498 - * children. GROUP's content may be wrapped in a SEQ - unwrap for ba2f29fRow pattern recognition patch (planner).
499 - * comparison. ba2f29fRow pattern recognition patch (planner).
500 - */ ba2f29fRow pattern recognition patch (planner).
501 1106 if (child->nodeType == RPR_PATTERN_GROUP && child->reluctant < 0) ba2f29fRow pattern recognition patch (planner).
502 - { ba2f29fRow pattern recognition patch (planner).
503 51 List *groupContent = child->children; ba2f29fRow pattern recognition patch (planner).
504 51 int groupChildCount; ba2f29fRow pattern recognition patch (planner).
505 51 int prefixLen = list_length(result); ba2f29fRow pattern recognition patch (planner).
506 - ba2f29fRow pattern recognition patch (planner).
507 - /* ba2f29fRow pattern recognition patch (planner).
508 - * If GROUP has single SEQ child, compare with SEQ's children. ba2f29fRow pattern recognition patch (planner).
509 - * e.g., (A B)+ internally contains sequence A B; compare against ba2f29fRow pattern recognition patch (planner).
510 - * that. ba2f29fRow pattern recognition patch (planner).
511 - */ ba2f29fRow pattern recognition patch (planner).
512 51 if (list_length(groupContent) == 1) ba2f29fRow pattern recognition patch (planner).
513 - { ba2f29fRow pattern recognition patch (planner).
514 51 RPRPatternNode *inner = (RPRPatternNode *) linitial(groupContent); ba2f29fRow pattern recognition patch (planner).
515 - ba2f29fRow pattern recognition patch (planner).
516 51 if (inner->nodeType == RPR_PATTERN_SEQ) ba2f29fRow pattern recognition patch (planner).
517 35 groupContent = inner->children; ba2f29fRow pattern recognition patch (planner).
518 51 } ba2f29fRow pattern recognition patch (planner).
519 - ba2f29fRow pattern recognition patch (planner).
520 51 groupChildCount = list_length(groupContent); ba2f29fRow pattern recognition patch (planner).
521 - ba2f29fRow pattern recognition patch (planner).
522 - /* ba2f29fRow pattern recognition patch (planner).
523 - * PREFIX MERGE: Check if preceding elements match. Keep absorbing ba2f29fRow pattern recognition patch (planner).
524 - * as long as we have matching prefixes. ba2f29fRow pattern recognition patch (planner).
525 - */ ba2f29fRow pattern recognition patch (planner).
526 66 while (prefixLen >= groupChildCount && groupChildCount > 0) ba2f29fRow pattern recognition patch (planner).
527 - { ba2f29fRow pattern recognition patch (planner).
528 21 List *prefixElements = NIL; ba2f29fRow pattern recognition patch (planner).
529 21 int j; ba2f29fRow pattern recognition patch (planner).
530 - ba2f29fRow pattern recognition patch (planner).
531 - /* Extract last groupChildCount elements from prefix */ ba2f29fRow pattern recognition patch (planner).
532 59 for (j = prefixLen - groupChildCount; j < prefixLen; j++) ba2f29fRow pattern recognition patch (planner).
533 - { ba2f29fRow pattern recognition patch (planner).
534 76 prefixElements = lappend(prefixElements, ba2f29fRow pattern recognition patch (planner).
535 38 list_nth(result, j)); ba2f29fRow pattern recognition patch (planner).
536 38 } ba2f29fRow pattern recognition patch (planner).
537 - ba2f29fRow pattern recognition patch (planner).
538 - /* Compare with GROUP's (possibly unwrapped) children */ ba2f29fRow pattern recognition patch (planner).
539 21 if (rprPatternChildrenEqual(prefixElements, groupContent) && ba2f29fRow pattern recognition patch (planner).
540 15 child->min < RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
541 - { ba2f29fRow pattern recognition patch (planner).
542 - /* ba2f29fRow pattern recognition patch (planner).
543 - * Match! Merge by incrementing GROUP's min. Remove the ba2f29fRow pattern recognition patch (planner).
544 - * prefix elements from output. ba2f29fRow pattern recognition patch (planner).
545 - */ ba2f29fRow pattern recognition patch (planner).
546 15 child->min += 1; ba2f29fRow pattern recognition patch (planner).
547 - ba2f29fRow pattern recognition patch (planner).
548 - /* Rebuild result without matched prefix */ ba2f29fRow pattern recognition patch (planner).
549 - { ba2f29fRow pattern recognition patch (planner).
550 15 List *trimmed = NIL; ba2f29fRow pattern recognition patch (planner).
551 - ba2f29fRow pattern recognition patch (planner).
552 20 for (j = 0; j < prefixLen - groupChildCount; j++) ba2f29fRow pattern recognition patch (planner).
553 - { ba2f29fRow pattern recognition patch (planner).
554 10 trimmed = lappend(trimmed, ba2f29fRow pattern recognition patch (planner).
555 5 list_nth(result, j)); ba2f29fRow pattern recognition patch (planner).
556 5 } ba2f29fRow pattern recognition patch (planner).
557 15 result = trimmed; ba2f29fRow pattern recognition patch (planner).
558 15 prefixLen = list_length(result); ba2f29fRow pattern recognition patch (planner).
559 15 } ba2f29fRow pattern recognition patch (planner).
560 15 } ba2f29fRow pattern recognition patch (planner).
561 - else ba2f29fRow pattern recognition patch (planner).
562 - { ba2f29fRow pattern recognition patch (planner).
563 6 list_free(prefixElements); ba2f29fRow pattern recognition patch (planner).
564 6 break; ba2f29fRow pattern recognition patch (planner).
565 - } ba2f29fRow pattern recognition patch (planner).
566 - ba2f29fRow pattern recognition patch (planner).
567 15 list_free(prefixElements); ba2f29fRow pattern recognition patch (planner).
568 21 } ba2f29fRow pattern recognition patch (planner).
569 - ba2f29fRow pattern recognition patch (planner).
570 - /* ba2f29fRow pattern recognition patch (planner).
571 - * SUFFIX MERGE: Check if following elements match. Keep absorbing ba2f29fRow pattern recognition patch (planner).
572 - * as long as we have matching suffixes. ba2f29fRow pattern recognition patch (planner).
573 - */ ba2f29fRow pattern recognition patch (planner).
574 62 while (i + groupChildCount < numChildren && groupChildCount > 0) ba2f29fRow pattern recognition patch (planner).
575 - { ba2f29fRow pattern recognition patch (planner).
576 22 List *suffixElements = NIL; ba2f29fRow pattern recognition patch (planner).
577 22 int j; ba2f29fRow pattern recognition patch (planner).
578 22 int suffixStart = i + 1; ba2f29fRow pattern recognition patch (planner).
579 - ba2f29fRow pattern recognition patch (planner).
580 - /* suffixStart always >= skipUntil after i adjustment */ ba2f29fRow pattern recognition patch (planner).
581 22 Assert(skipUntil <= suffixStart); ba2f29fRow pattern recognition patch (planner).
582 - ba2f29fRow pattern recognition patch (planner).
583 - /* Extract next groupChildCount elements as suffix */ ba2f29fRow pattern recognition patch (planner).
584 54 for (j = 0; j < groupChildCount; j++) ba2f29fRow pattern recognition patch (planner).
585 - { ba2f29fRow pattern recognition patch (planner).
586 32 int idx = suffixStart + j; ba2f29fRow pattern recognition patch (planner).
587 - ba2f29fRow pattern recognition patch (planner).
588 - /* while condition guarantees idx < numChildren */ ba2f29fRow pattern recognition patch (planner).
589 32 Assert(idx < numChildren); ba2f29fRow pattern recognition patch (planner).
590 64 suffixElements = lappend(suffixElements, ba2f29fRow pattern recognition patch (planner).
591 32 list_nth(children, idx)); ba2f29fRow pattern recognition patch (planner).
592 32 } ba2f29fRow pattern recognition patch (planner).
593 - ba2f29fRow pattern recognition patch (planner).
594 - /* Compare with GROUP's children */ ba2f29fRow pattern recognition patch (planner).
595 33 if (list_length(suffixElements) == groupChildCount && ba2f29fRow pattern recognition patch (planner).
596 22 rprPatternChildrenEqual(suffixElements, groupContent) && ba2f29fRow pattern recognition patch (planner).
597 11 child->min < RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
598 - { ba2f29fRow pattern recognition patch (planner).
599 - /* ba2f29fRow pattern recognition patch (planner).
600 - * Match! Absorb suffix by incrementing min and skipping. ba2f29fRow pattern recognition patch (planner).
601 - */ ba2f29fRow pattern recognition patch (planner).
602 11 child->min += 1; ba2f29fRow pattern recognition patch (planner).
603 11 skipUntil = suffixStart + groupChildCount; ba2f29fRow pattern recognition patch (planner).
604 - ba2f29fRow pattern recognition patch (planner).
605 - /* ba2f29fRow pattern recognition patch (planner).
606 - * Update i to continue suffix check after absorbed ba2f29fRow pattern recognition patch (planner).
607 - * elements ba2f29fRow pattern recognition patch (planner).
608 - */ ba2f29fRow pattern recognition patch (planner).
609 11 i = skipUntil - 1; ba2f29fRow pattern recognition patch (planner).
610 11 } ba2f29fRow pattern recognition patch (planner).
611 - else ba2f29fRow pattern recognition patch (planner).
612 - { ba2f29fRow pattern recognition patch (planner).
613 11 list_free(suffixElements); ba2f29fRow pattern recognition patch (planner).
614 11 break; ba2f29fRow pattern recognition patch (planner).
615 - } ba2f29fRow pattern recognition patch (planner).
616 - ba2f29fRow pattern recognition patch (planner).
617 11 list_free(suffixElements); ba2f29fRow pattern recognition patch (planner).
618 22 } ba2f29fRow pattern recognition patch (planner).
619 51 } ba2f29fRow pattern recognition patch (planner).
620 - ba2f29fRow pattern recognition patch (planner).
621 1106 result = lappend(result, child); ba2f29fRow pattern recognition patch (planner).
622 1106 } ba2f29fRow pattern recognition patch (planner).
623 - ba2f29fRow pattern recognition patch (planner).
624 700 return result; ba2f29fRow pattern recognition patch (planner).
625 350 } ba2f29fRow pattern recognition patch (planner).
optimizeSeqPattern() lines 640-659
Modified Lines Coverage: 7/7 lines (100.0%)
LineHitsSourceCommit
640 350 optimizeSeqPattern(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
641 - { ba2f29fRow pattern recognition patch (planner).
642 - /* Recursively optimize children and flatten nested SEQ/GROUP{1,1} */ ba2f29fRow pattern recognition patch (planner).
643 350 pattern->children = flattenSeqChildren(pattern->children); ba2f29fRow pattern recognition patch (planner).
644 - ba2f29fRow pattern recognition patch (planner).
645 - /* Merge consecutive identical VAR nodes */ ba2f29fRow pattern recognition patch (planner).
646 350 pattern->children = mergeConsecutiveVars(pattern->children); ba2f29fRow pattern recognition patch (planner).
647 - ba2f29fRow pattern recognition patch (planner).
648 - /* Merge consecutive identical GROUP nodes */ ba2f29fRow pattern recognition patch (planner).
649 350 pattern->children = mergeConsecutiveGroups(pattern->children); ba2f29fRow pattern recognition patch (planner).
650 - ba2f29fRow pattern recognition patch (planner).
651 - /* Merge consecutive identical ALT nodes into GROUP */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
652 350 pattern->children = mergeConsecutiveAlts(pattern->children); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
653 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
654 - /* Merge prefix/suffix into GROUP with matching children */ ba2f29fRow pattern recognition patch (planner).
655 350 pattern->children = mergeGroupPrefixSuffix(pattern->children); ba2f29fRow pattern recognition patch (planner).
656 - ba2f29fRow pattern recognition patch (planner).
657 - /* Unwrap single-item SEQ */ ba2f29fRow pattern recognition patch (planner).
658 350 return tryUnwrapSingleChild(pattern); ba2f29fRow pattern recognition patch (planner).
659 - } ba2f29fRow pattern recognition patch (planner).
flattenAltChildren() lines 672-689
Modified Lines Coverage: 12/12 lines (100.0%)
LineHitsSourceCommit
672 129 flattenAltChildren(List *children) ba2f29fRow pattern recognition patch (planner).
673 - { ba2f29fRow pattern recognition patch (planner).
674 129 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
675 129 List *newChildren = NIL; ba2f29fRow pattern recognition patch (planner).
676 - ba2f29fRow pattern recognition patch (planner).
677 410 foreach(lc, children) ba2f29fRow pattern recognition patch (planner).
678 - { ba2f29fRow pattern recognition patch (planner).
679 281 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
680 281 RPRPatternNode *opt = optimizeRPRPattern(child); ba2f29fRow pattern recognition patch (planner).
681 - ba2f29fRow pattern recognition patch (planner).
682 281 if (opt->nodeType == RPR_PATTERN_ALT) ba2f29fRow pattern recognition patch (planner).
683 2 newChildren = list_concat(newChildren, list_copy(opt->children)); ba2f29fRow pattern recognition patch (planner).
684 - else ba2f29fRow pattern recognition patch (planner).
685 279 newChildren = lappend(newChildren, opt); ba2f29fRow pattern recognition patch (planner).
686 281 } ba2f29fRow pattern recognition patch (planner).
687 - ba2f29fRow pattern recognition patch (planner).
688 258 return newChildren; ba2f29fRow pattern recognition patch (planner).
689 129 } ba2f29fRow pattern recognition patch (planner).
removeDuplicateAlternatives() lines 702-727
Modified Lines Coverage: 17/17 lines (100.0%)
LineHitsSourceCommit
702 129 removeDuplicateAlternatives(List *children) ba2f29fRow pattern recognition patch (planner).
703 - { ba2f29fRow pattern recognition patch (planner).
704 129 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
705 129 ListCell *lc2; ba2f29fRow pattern recognition patch (planner).
706 129 List *uniqueChildren = NIL; ba2f29fRow pattern recognition patch (planner).
707 - ba2f29fRow pattern recognition patch (planner).
708 412 foreach(lc, children) ba2f29fRow pattern recognition patch (planner).
709 - { ba2f29fRow pattern recognition patch (planner).
710 283 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
711 283 bool isDuplicate = false; ba2f29fRow pattern recognition patch (planner).
712 - ba2f29fRow pattern recognition patch (planner).
713 468 foreach(lc2, uniqueChildren) ba2f29fRow pattern recognition patch (planner).
714 - { ba2f29fRow pattern recognition patch (planner).
715 185 if (rprPatternEqual((RPRPatternNode *) lfirst(lc2), child)) ba2f29fRow pattern recognition patch (planner).
716 - { ba2f29fRow pattern recognition patch (planner).
717 4 isDuplicate = true; ba2f29fRow pattern recognition patch (planner).
718 4 break; ba2f29fRow pattern recognition patch (planner).
719 - } ba2f29fRow pattern recognition patch (planner).
720 181 } ba2f29fRow pattern recognition patch (planner).
721 - ba2f29fRow pattern recognition patch (planner).
722 283 if (!isDuplicate) ba2f29fRow pattern recognition patch (planner).
723 279 uniqueChildren = lappend(uniqueChildren, child); ba2f29fRow pattern recognition patch (planner).
724 283 } ba2f29fRow pattern recognition patch (planner).
725 - ba2f29fRow pattern recognition patch (planner).
726 258 return uniqueChildren; ba2f29fRow pattern recognition patch (planner).
727 129 } ba2f29fRow pattern recognition patch (planner).
optimizeAltPattern() lines 739-749
Modified Lines Coverage: 4/4 lines (100.0%)
LineHitsSourceCommit
739 129 optimizeAltPattern(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
740 - { ba2f29fRow pattern recognition patch (planner).
741 - /* Recursively optimize children and flatten nested ALT */ ba2f29fRow pattern recognition patch (planner).
742 129 pattern->children = flattenAltChildren(pattern->children); ba2f29fRow pattern recognition patch (planner).
743 - ba2f29fRow pattern recognition patch (planner).
744 - /* Remove duplicate alternatives */ ba2f29fRow pattern recognition patch (planner).
745 129 pattern->children = removeDuplicateAlternatives(pattern->children); ba2f29fRow pattern recognition patch (planner).
746 - ba2f29fRow pattern recognition patch (planner).
747 - /* Unwrap single-item ALT */ ba2f29fRow pattern recognition patch (planner).
748 129 return tryUnwrapSingleChild(pattern); ba2f29fRow pattern recognition patch (planner).
749 - } ba2f29fRow pattern recognition patch (planner).
tryMultiplyQuantifiers() lines 769-829
Modified Lines Coverage: 34/35 lines (97.1%)
LineHitsSourceCommit
769 1776 tryMultiplyQuantifiers(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
770 - { ba2f29fRow pattern recognition patch (planner).
771 1776 RPRPatternNode *child; ba2f29fRow pattern recognition patch (planner).
772 1776 int64 new_min_64; ba2f29fRow pattern recognition patch (planner).
773 1776 int64 new_max_64; ba2f29fRow pattern recognition patch (planner).
774 - ba2f29fRow pattern recognition patch (planner).
775 - /* Parser always creates GROUP with exactly one child */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
776 1776 Assert(list_length(pattern->children) == 1); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
777 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
778 1776 if (pattern->reluctant >= 0) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
779 0 return pattern; ba2f29fRow pattern recognition patch (planner).
780 - ba2f29fRow pattern recognition patch (planner).
781 1776 child = (RPRPatternNode *) linitial(pattern->children); ba2f29fRow pattern recognition patch (planner).
782 - ba2f29fRow pattern recognition patch (planner).
783 1776 if ((child->nodeType != RPR_PATTERN_VAR && 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
784 696 child->nodeType != RPR_PATTERN_GROUP) || 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
785 1080 child->reluctant >= 0) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
786 1211 return pattern; ba2f29fRow pattern recognition patch (planner).
787 - ba2f29fRow pattern recognition patch (planner).
788 - /* Case 1: Both unbounded - (A*)* -> A*, (A+)+ -> A+ */ ba2f29fRow pattern recognition patch (planner).
789 565 if (child->max == RPR_QUANTITY_INF && pattern->max == RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
790 - { ba2f29fRow pattern recognition patch (planner).
791 22 new_min_64 = (int64) child->min * pattern->min; ba2f29fRow pattern recognition patch (planner).
792 22 if (new_min_64 >= RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
793 1 return pattern; /* overflow, skip optimization */ ba2f29fRow pattern recognition patch (planner).
794 - ba2f29fRow pattern recognition patch (planner).
795 21 child->min = (int) new_min_64; ba2f29fRow pattern recognition patch (planner).
796 21 child->max = RPR_QUANTITY_INF; ba2f29fRow pattern recognition patch (planner).
797 21 return child; ba2f29fRow pattern recognition patch (planner).
798 - } ba2f29fRow pattern recognition patch (planner).
799 - ba2f29fRow pattern recognition patch (planner).
800 - /* ba2f29fRow pattern recognition patch (planner).
801 - * Case 2/3: Safe when child is finite AND (outer is exact OR child is ba2f29fRow pattern recognition patch (planner).
802 - * {1,1}) ba2f29fRow pattern recognition patch (planner).
803 - */ ba2f29fRow pattern recognition patch (planner).
804 549 if (child->max != RPR_QUANTITY_INF && ba2f29fRow pattern recognition patch (planner).
805 537 (pattern->min == pattern->max || ba2f29fRow pattern recognition patch (planner).
806 522 (child->min == 1 && child->max == 1))) ba2f29fRow pattern recognition patch (planner).
807 - { ba2f29fRow pattern recognition patch (planner).
808 20 new_min_64 = (int64) pattern->min * child->min; ba2f29fRow pattern recognition patch (planner).
809 20 if (new_min_64 >= RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
810 1 return pattern; ba2f29fRow pattern recognition patch (planner).
811 - ba2f29fRow pattern recognition patch (planner).
812 19 if (pattern->max == RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
813 5 new_max_64 = RPR_QUANTITY_INF; ba2f29fRow pattern recognition patch (planner).
814 - else ba2f29fRow pattern recognition patch (planner).
815 - { ba2f29fRow pattern recognition patch (planner).
816 14 new_max_64 = (int64) pattern->max * child->max; ba2f29fRow pattern recognition patch (planner).
817 - ba2f29fRow pattern recognition patch (planner).
818 14 if (new_max_64 >= RPR_QUANTITY_INF) ba2f29fRow pattern recognition patch (planner).
819 1 return pattern; ba2f29fRow pattern recognition patch (planner).
820 - } ba2f29fRow pattern recognition patch (planner).
821 - ba2f29fRow pattern recognition patch (planner).
822 18 child->min = (int) new_min_64; ba2f29fRow pattern recognition patch (planner).
823 18 child->max = (int) new_max_64; ba2f29fRow pattern recognition patch (planner).
824 18 return child; ba2f29fRow pattern recognition patch (planner).
825 - } ba2f29fRow pattern recognition patch (planner).
826 - ba2f29fRow pattern recognition patch (planner).
827 - /* Not safe to multiply */ ba2f29fRow pattern recognition patch (planner).
828 523 return pattern; ba2f29fRow pattern recognition patch (planner).
829 746 } ba2f29fRow pattern recognition patch (planner).
tryUnwrapGroup() lines 845-853
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
845 707 tryUnwrapGroup(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
846 - { ba2f29fRow pattern recognition patch (planner).
847 707 if (pattern->min != 1 || pattern->max != 1 || pattern->reluctant >= 0) ba2f29fRow pattern recognition patch (planner).
848 616 return pattern; ba2f29fRow pattern recognition patch (planner).
849 - ba2f29fRow pattern recognition patch (planner).
850 - /* Parser always creates GROUP with single child */ ba2f29fRow pattern recognition patch (planner).
851 91 Assert(list_length(pattern->children) == 1); ba2f29fRow pattern recognition patch (planner).
852 91 return (RPRPatternNode *) linitial(pattern->children); ba2f29fRow pattern recognition patch (planner).
853 707 } ba2f29fRow pattern recognition patch (planner).
optimizeGroupPattern() lines 864-887
Modified Lines Coverage: 15/15 lines (100.0%)
LineHitsSourceCommit
864 746 optimizeGroupPattern(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
865 - { ba2f29fRow pattern recognition patch (planner).
866 746 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
867 746 List *newChildren; ba2f29fRow pattern recognition patch (planner).
868 746 RPRPatternNode *result; ba2f29fRow pattern recognition patch (planner).
869 - ba2f29fRow pattern recognition patch (planner).
870 - /* Recursively optimize children */ ba2f29fRow pattern recognition patch (planner).
871 746 newChildren = NIL; ba2f29fRow pattern recognition patch (planner).
872 1492 foreach(lc, pattern->children) ba2f29fRow pattern recognition patch (planner).
873 - { ba2f29fRow pattern recognition patch (planner).
874 746 RPRPatternNode *child = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
875 - ba2f29fRow pattern recognition patch (planner).
876 746 newChildren = lappend(newChildren, optimizeRPRPattern(child)); ba2f29fRow pattern recognition patch (planner).
877 746 } ba2f29fRow pattern recognition patch (planner).
878 746 pattern->children = newChildren; ba2f29fRow pattern recognition patch (planner).
879 - ba2f29fRow pattern recognition patch (planner).
880 - /* Try quantifier multiplication */ ba2f29fRow pattern recognition patch (planner).
881 746 result = tryMultiplyQuantifiers(pattern); ba2f29fRow pattern recognition patch (planner).
882 746 if (result != pattern) ba2f29fRow pattern recognition patch (planner).
883 39 return result; ba2f29fRow pattern recognition patch (planner).
884 - ba2f29fRow pattern recognition patch (planner).
885 - /* Try unwrapping GROUP{1,1} */ ba2f29fRow pattern recognition patch (planner).
886 707 return tryUnwrapGroup(pattern); ba2f29fRow pattern recognition patch (planner).
887 746 } ba2f29fRow pattern recognition patch (planner).
optimizeRPRPattern() lines 897-915
Modified Lines Coverage: 8/9 lines (88.9%)
LineHitsSourceCommit
897 2647 optimizeRPRPattern(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
898 - { ba2f29fRow pattern recognition patch (planner).
899 - /* Pattern nodes from parser are never NULL */ ba2f29fRow pattern recognition patch (planner).
900 2647 Assert(pattern != NULL); ba2f29fRow pattern recognition patch (planner).
901 - ba2f29fRow pattern recognition patch (planner).
902 2647 switch (pattern->nodeType) ba2f29fRow pattern recognition patch (planner).
903 - { ba2f29fRow pattern recognition patch (planner).
904 - case RPR_PATTERN_VAR: ba2f29fRow pattern recognition patch (planner).
905 1422 return pattern; ba2f29fRow pattern recognition patch (planner).
906 - case RPR_PATTERN_SEQ: ba2f29fRow pattern recognition patch (planner).
907 350 return optimizeSeqPattern(pattern); ba2f29fRow pattern recognition patch (planner).
908 - case RPR_PATTERN_ALT: ba2f29fRow pattern recognition patch (planner).
909 129 return optimizeAltPattern(pattern); ba2f29fRow pattern recognition patch (planner).
910 - case RPR_PATTERN_GROUP: ba2f29fRow pattern recognition patch (planner).
911 746 return optimizeGroupPattern(pattern); ba2f29fRow pattern recognition patch (planner).
912 - } ba2f29fRow pattern recognition patch (planner).
913 - ba2f29fRow pattern recognition patch (planner).
914 0 return pattern; /* keep compiler quiet */ ba2f29fRow pattern recognition patch (planner).
915 2647 } ba2f29fRow pattern recognition patch (planner).
collectDefineVariables() lines 926-940
Modified Lines Coverage: 9/9 lines (100.0%)
LineHitsSourceCommit
926 462 collectDefineVariables(List *defineVariableList, char **varNames) ba2f29fRow pattern recognition patch (planner).
927 - { ba2f29fRow pattern recognition patch (planner).
928 462 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
929 462 int numVars = 0; ba2f29fRow pattern recognition patch (planner).
930 - ba2f29fRow pattern recognition patch (planner).
931 1706 foreach(lc, defineVariableList) ba2f29fRow pattern recognition patch (planner).
932 - { ba2f29fRow pattern recognition patch (planner).
933 - /* Parser already checked this limit in transformDefineClause */ ba2f29fRow pattern recognition patch (planner).
934 1244 Assert(numVars < RPR_VARID_MAX); ba2f29fRow pattern recognition patch (planner).
935 - ba2f29fRow pattern recognition patch (planner).
936 1244 varNames[numVars++] = strVal(lfirst(lc)); ba2f29fRow pattern recognition patch (planner).
937 1244 } ba2f29fRow pattern recognition patch (planner).
938 - ba2f29fRow pattern recognition patch (planner).
939 924 return numVars; ba2f29fRow pattern recognition patch (planner).
940 462 } ba2f29fRow pattern recognition patch (planner).
scanRPRPatternRecursive() lines 951-1033
Modified Lines Coverage: 38/38 lines (100.0%)
LineHitsSourceCommit
951 2161 scanRPRPatternRecursive(RPRPatternNode *node, char **varNames, int *numVars, ba2f29fRow pattern recognition patch (planner).
952 - int *numElements, RPRDepth depth, RPRDepth *maxDepth) ba2f29fRow pattern recognition patch (planner).
953 - { ba2f29fRow pattern recognition patch (planner).
954 2161 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
955 2161 int i; ba2f29fRow pattern recognition patch (planner).
956 - ba2f29fRow pattern recognition patch (planner).
957 - /* Pattern nodes from parser are never NULL */ ba2f29fRow pattern recognition patch (planner).
958 2161 Assert(node != NULL); ba2f29fRow pattern recognition patch (planner).
959 - ba2f29fRow pattern recognition patch (planner).
960 - /* Check recursion depth limit before overflow occurs */ ba2f29fRow pattern recognition patch (planner).
961 2161 if (depth >= RPR_DEPTH_MAX) ba2f29fRow pattern recognition patch (planner).
962 1 ereport(ERROR, ba2f29fRow pattern recognition patch (planner).
963 - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), ba2f29fRow pattern recognition patch (planner).
964 - errmsg("pattern nesting too deep"), ba2f29fRow pattern recognition patch (planner).
965 - errdetail("Pattern nesting depth %d exceeds maximum %d.", ba2f29fRow pattern recognition patch (planner).
966 - depth, RPR_DEPTH_MAX - 1))); ba2f29fRow pattern recognition patch (planner).
967 - ba2f29fRow pattern recognition patch (planner).
968 - /* Track maximum depth */ ba2f29fRow pattern recognition patch (planner).
969 2160 if (depth > *maxDepth) ba2f29fRow pattern recognition patch (planner).
970 707 *maxDepth = depth; ba2f29fRow pattern recognition patch (planner).
971 - ba2f29fRow pattern recognition patch (planner).
972 2160 switch (node->nodeType) ba2f29fRow pattern recognition patch (planner).
973 - { ba2f29fRow pattern recognition patch (planner).
974 - case RPR_PATTERN_VAR: ba2f29fRow pattern recognition patch (planner).
975 - /* Count element */ ba2f29fRow pattern recognition patch (planner).
976 1298 (*numElements)++; ba2f29fRow pattern recognition patch (planner).
977 - ba2f29fRow pattern recognition patch (planner).
978 - /* Collect variable name if not already present */ ba2f29fRow pattern recognition patch (planner).
979 33715 for (i = 0; i < *numVars; i++) ba2f29fRow pattern recognition patch (planner).
980 - { ba2f29fRow pattern recognition patch (planner).
981 33709 if (strcmp(varNames[i], node->varName) == 0) ba2f29fRow pattern recognition patch (planner).
982 1292 return; /* Already have this variable */ ba2f29fRow pattern recognition patch (planner).
983 32417 } ba2f29fRow pattern recognition patch (planner).
984 - ba2f29fRow pattern recognition patch (planner).
985 - /* ba2f29fRow pattern recognition patch (planner).
986 - * Variable not in DEFINE clause - this is valid per SQL standard. ba2f29fRow pattern recognition patch (planner).
987 - * Such variables are implicitly TRUE. Add to varNames so they get ba2f29fRow pattern recognition patch (planner).
988 - * a varId >= defineVariableList length, which executor treats as ba2f29fRow pattern recognition patch (planner).
989 - * TRUE. ba2f29fRow pattern recognition patch (planner).
990 - */ ba2f29fRow pattern recognition patch (planner).
991 6 Assert(*numVars < RPR_VARID_MAX); ba2f29fRow pattern recognition patch (planner).
992 6 varNames[(*numVars)++] = node->varName; ba2f29fRow pattern recognition patch (planner).
993 6 break; ba2f29fRow pattern recognition patch (planner).
994 - ba2f29fRow pattern recognition patch (planner).
995 - case RPR_PATTERN_SEQ: ba2f29fRow pattern recognition patch (planner).
996 - /* Sequence: just recurse into children */ ba2f29fRow pattern recognition patch (planner).
997 1306 foreach(lc, node->children) ba2f29fRow pattern recognition patch (planner).
998 - { ba2f29fRow pattern recognition patch (planner).
999 2014 scanRPRPatternRecursive((RPRPatternNode *) lfirst(lc), varNames, ba2f29fRow pattern recognition patch (planner).
1000 1007 numVars, numElements, depth, maxDepth); ba2f29fRow pattern recognition patch (planner).
1001 1007 } ba2f29fRow pattern recognition patch (planner).
1002 299 break; ba2f29fRow pattern recognition patch (planner).
1003 - ba2f29fRow pattern recognition patch (planner).
1004 - case RPR_PATTERN_GROUP: ba2f29fRow pattern recognition patch (planner).
1005 - /* Add BEGIN element if group has non-trivial quantifier */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1006 457 if (node->min != 1 || node->max != 1) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1007 613 (*numElements)++; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1008 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1009 - /* Recurse into children at increased depth */ ba2f29fRow pattern recognition patch (planner).
1010 1480 foreach(lc, node->children) ba2f29fRow pattern recognition patch (planner).
1011 - { ba2f29fRow pattern recognition patch (planner).
1012 1226 scanRPRPatternRecursive((RPRPatternNode *) lfirst(lc), varNames, ba2f29fRow pattern recognition patch (planner).
1013 613 numVars, numElements, depth + 1, maxDepth); ba2f29fRow pattern recognition patch (planner).
1014 613 } ba2f29fRow pattern recognition patch (planner).
1015 - ba2f29fRow pattern recognition patch (planner).
1016 - /* Add END element if group has non-trivial quantifier */ ba2f29fRow pattern recognition patch (planner).
1017 359 if (node->min != 1 || node->max != 1) ba2f29fRow pattern recognition patch (planner).
1018 359 (*numElements)++; ba2f29fRow pattern recognition patch (planner).
1019 359 break; ba2f29fRow pattern recognition patch (planner).
1020 - ba2f29fRow pattern recognition patch (planner).
1021 - case RPR_PATTERN_ALT: ba2f29fRow pattern recognition patch (planner).
1022 - /* Count ALT start element */ ba2f29fRow pattern recognition patch (planner).
1023 106 (*numElements)++; ba2f29fRow pattern recognition patch (planner).
1024 - ba2f29fRow pattern recognition patch (planner).
1025 - /* Recurse into children at increased depth */ ba2f29fRow pattern recognition patch (planner).
1026 341 foreach(lc, node->children) ba2f29fRow pattern recognition patch (planner).
1027 - { ba2f29fRow pattern recognition patch (planner).
1028 470 scanRPRPatternRecursive((RPRPatternNode *) lfirst(lc), varNames, ba2f29fRow pattern recognition patch (planner).
1029 235 numVars, numElements, depth + 1, maxDepth); ba2f29fRow pattern recognition patch (planner).
1030 235 } ba2f29fRow pattern recognition patch (planner).
1031 106 break; ba2f29fRow pattern recognition patch (planner).
1032 - } ba2f29fRow pattern recognition patch (planner).
1033 2062 } ba2f29fRow pattern recognition patch (planner).
scanRPRPattern() lines 1044-1060
Modified Lines Coverage: 7/8 lines (87.5%)
LineHitsSourceCommit
1044 462 scanRPRPattern(RPRPatternNode *node, char **varNames, int *numVars, ba2f29fRow pattern recognition patch (planner).
1045 - int *numElements, RPRDepth *maxDepth) ba2f29fRow pattern recognition patch (planner).
1046 - { ba2f29fRow pattern recognition patch (planner).
1047 462 *numElements = 0; ba2f29fRow pattern recognition patch (planner).
1048 462 *maxDepth = 0; ba2f29fRow pattern recognition patch (planner).
1049 - ba2f29fRow pattern recognition patch (planner).
1050 462 scanRPRPatternRecursive(node, varNames, numVars, numElements, 0, maxDepth); ba2f29fRow pattern recognition patch (planner).
1051 - ba2f29fRow pattern recognition patch (planner).
1052 462 (*numElements)++; /* +1 for FIN marker */ ba2f29fRow pattern recognition patch (planner).
1053 - ba2f29fRow pattern recognition patch (planner).
1054 462 if (*numElements > RPR_ELEMIDX_MAX) ba2f29fRow pattern recognition patch (planner).
1055 0 ereport(ERROR, ba2f29fRow pattern recognition patch (planner).
1056 - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), ba2f29fRow pattern recognition patch (planner).
1057 - errmsg("pattern too complex"), ba2f29fRow pattern recognition patch (planner).
1058 - errdetail("Pattern has %d elements, maximum is %d.", ba2f29fRow pattern recognition patch (planner).
1059 - *numElements, RPR_ELEMIDX_MAX))); ba2f29fRow pattern recognition patch (planner).
1060 462 } ba2f29fRow pattern recognition patch (planner).
allocateRPRPattern() lines 1070-1092
Modified Lines Coverage: 15/15 lines (100.0%)
LineHitsSourceCommit
1070 461 allocateRPRPattern(int numVars, int numElements, RPRDepth maxDepth, ba2f29fRow pattern recognition patch (planner).
1071 - char **varNamesStack) ba2f29fRow pattern recognition patch (planner).
1072 - { ba2f29fRow pattern recognition patch (planner).
1073 461 RPRPattern *result; ba2f29fRow pattern recognition patch (planner).
1074 461 int i; ba2f29fRow pattern recognition patch (planner).
1075 - ba2f29fRow pattern recognition patch (planner).
1076 461 result = makeNode(RPRPattern); ba2f29fRow pattern recognition patch (planner).
1077 461 result->numVars = numVars; ba2f29fRow pattern recognition patch (planner).
1078 461 result->maxDepth = maxDepth + 1; /* +1: depth is 0-based */ ba2f29fRow pattern recognition patch (planner).
1079 461 result->numElements = numElements; ba2f29fRow pattern recognition patch (planner).
1080 - ba2f29fRow pattern recognition patch (planner).
1081 - /* Copy varNames (pattern must have at least one variable) */ ba2f29fRow pattern recognition patch (planner).
1082 461 Assert(numVars > 0); ba2f29fRow pattern recognition patch (planner).
1083 461 result->varNames = palloc(numVars * sizeof(char *)); ba2f29fRow pattern recognition patch (planner).
1084 1710 for (i = 0; i < numVars; i++) ba2f29fRow pattern recognition patch (planner).
1085 1249 result->varNames[i] = pstrdup(varNamesStack[i]); ba2f29fRow pattern recognition patch (planner).
1086 - ba2f29fRow pattern recognition patch (planner).
1087 - /* Allocate elements array (zero-init for reserved fields) */ ba2f29fRow pattern recognition patch (planner).
1088 461 Assert(numElements >= 2); ba2f29fRow pattern recognition patch (planner).
1089 461 result->elements = palloc0(numElements * sizeof(RPRPatternElement)); ba2f29fRow pattern recognition patch (planner).
1090 - ba2f29fRow pattern recognition patch (planner).
1091 922 return result; ba2f29fRow pattern recognition patch (planner).
1092 461 } ba2f29fRow pattern recognition patch (planner).
getVarIdFromPattern() lines 1101-1112
Modified Lines Coverage: 6/8 lines (75.0%)
LineHitsSourceCommit
1101 1298 getVarIdFromPattern(RPRPattern *pat, const char *varName) ba2f29fRow pattern recognition patch (planner).
1102 - { ba2f29fRow pattern recognition patch (planner).
1103 35013 for (int i = 0; i < pat->numVars; i++) ba2f29fRow pattern recognition patch (planner).
1104 - { ba2f29fRow pattern recognition patch (planner).
1105 33715 if (strcmp(pat->varNames[i], varName) == 0) ba2f29fRow pattern recognition patch (planner).
1106 1298 return (RPRVarId) i; ba2f29fRow pattern recognition patch (planner).
1107 32417 } ba2f29fRow pattern recognition patch (planner).
1108 - ba2f29fRow pattern recognition patch (planner).
1109 - /* Should not happen - variable should already be collected */ ba2f29fRow pattern recognition patch (planner).
1110 0 elog(ERROR, "pattern variable \"%s\" not found", varName); ba2f29fRow pattern recognition patch (planner).
1111 0 pg_unreachable(); ba2f29fRow pattern recognition patch (planner).
1112 1298 } ba2f29fRow pattern recognition patch (planner).
fillRPRPatternVar() lines 1119-1133
Modified Lines Coverage: 12/13 lines (92.3%)
LineHitsSourceCommit
1119 1298 fillRPRPatternVar(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth depth) ba2f29fRow pattern recognition patch (planner).
1120 - { ba2f29fRow pattern recognition patch (planner).
1121 1298 RPRPatternElement *elem = &pat->elements[*idx]; ba2f29fRow pattern recognition patch (planner).
1122 - ba2f29fRow pattern recognition patch (planner).
1123 1298 memset(elem, 0, sizeof(RPRPatternElement)); ba2f29fRow pattern recognition patch (planner).
1124 1298 elem->varId = getVarIdFromPattern(pat, node->varName); ba2f29fRow pattern recognition patch (planner).
1125 1298 elem->depth = depth; ba2f29fRow pattern recognition patch (planner).
1126 1298 elem->min = node->min; ba2f29fRow pattern recognition patch (planner).
1127 1298 elem->max = (node->max == INT_MAX) ? RPR_QUANTITY_INF : node->max; ba2f29fRow pattern recognition patch (planner).
1128 1298 elem->next = RPR_ELEMIDX_INVALID; ba2f29fRow pattern recognition patch (planner).
1129 1298 elem->jump = RPR_ELEMIDX_INVALID; ba2f29fRow pattern recognition patch (planner).
1130 1298 if (node->reluctant >= 0) ba2f29fRow pattern recognition patch (planner).
1131 0 elem->flags |= RPR_ELEM_RELUCTANT; ba2f29fRow pattern recognition patch (planner).
1132 1298 (*idx)++; ba2f29fRow pattern recognition patch (planner).
1133 1298 } ba2f29fRow pattern recognition patch (planner).
fillRPRPatternGroup() lines 1143-1193
Modified Lines Coverage: 36/38 lines (94.7%)
LineHitsSourceCommit
1143 359 fillRPRPatternGroup(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth depth) ba2f29fRow pattern recognition patch (planner).
1144 - { ba2f29fRow pattern recognition patch (planner).
1145 359 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
1146 359 int groupStartIdx = *idx; ba2f29fRow pattern recognition patch (planner).
1147 359 int beginIdx = -1; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1148 - ba2f29fRow pattern recognition patch (planner).
1149 - /* Add BEGIN marker if group has non-trivial quantifier */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1150 359 if (node->min != 1 || node->max != 1) ba2f29fRow pattern recognition patch (planner).
1151 - { ba2f29fRow pattern recognition patch (planner).
1152 359 RPRPatternElement *elem = &pat->elements[*idx]; ba2f29fRow pattern recognition patch (planner).
1153 - ba2f29fRow pattern recognition patch (planner).
1154 359 beginIdx = *idx; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1155 359 memset(elem, 0, sizeof(RPRPatternElement)); ba2f29fRow pattern recognition patch (planner).
1156 359 elem->varId = RPR_VARID_BEGIN; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1157 359 elem->depth = depth; ba2f29fRow pattern recognition patch (planner).
1158 359 elem->min = node->min; ba2f29fRow pattern recognition patch (planner).
1159 359 elem->max = (node->max == INT_MAX) ? RPR_QUANTITY_INF : node->max; ba2f29fRow pattern recognition patch (planner).
1160 359 elem->next = RPR_ELEMIDX_INVALID; /* set by finalize */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1161 359 elem->jump = RPR_ELEMIDX_INVALID; /* set after END */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1162 359 if (node->reluctant >= 0) ba2f29fRow pattern recognition patch (planner).
1163 0 elem->flags |= RPR_ELEM_RELUCTANT; ba2f29fRow pattern recognition patch (planner).
1164 359 (*idx)++; ba2f29fRow pattern recognition patch (planner).
1165 359 groupStartIdx = *idx; /* children start after BEGIN */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1166 359 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1167 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1168 718 foreach(lc, node->children) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1169 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1170 359 fillRPRPattern((RPRPatternNode *) lfirst(lc), pat, idx, depth + 1); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1171 359 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1172 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1173 - /* Add group end marker if group has non-trivial quantifier */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1174 359 if (node->min != 1 || node->max != 1) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1175 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1176 359 RPRPatternElement *beginElem = &pat->elements[beginIdx]; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1177 359 RPRPatternElement *endElem = &pat->elements[*idx]; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1178 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1179 359 memset(endElem, 0, sizeof(RPRPatternElement)); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1180 359 endElem->varId = RPR_VARID_END; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1181 359 endElem->depth = depth; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1182 359 endElem->min = node->min; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1183 359 endElem->max = (node->max == INT_MAX) ? RPR_QUANTITY_INF : node->max; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1184 359 endElem->next = RPR_ELEMIDX_INVALID; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1185 359 endElem->jump = groupStartIdx; /* loop to first child */ 9d2796cReview NFA executor and add comprehensive runtime tests
1186 359 if (node->reluctant >= 0) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1187 0 endElem->flags |= RPR_ELEM_RELUCTANT; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1188 359 (*idx)++; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1189 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1190 - /* Set BEGIN skip pointer (next is set by finalize) */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1191 359 beginElem->jump = *idx; /* skip: go to after END */ 9d2796cReview NFA executor and add comprehensive runtime tests
1192 359 } ba2f29fRow pattern recognition patch (planner).
1193 359 } ba2f29fRow pattern recognition patch (planner).
fillRPRPatternAlt() lines 1203-1278
Modified Lines Coverage: 46/46 lines (100.0%)
LineHitsSourceCommit
1203 106 fillRPRPatternAlt(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth depth) ba2f29fRow pattern recognition patch (planner).
1204 - { ba2f29fRow pattern recognition patch (planner).
1205 106 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
1206 106 RPRPatternElement *elem; ba2f29fRow pattern recognition patch (planner).
1207 106 List *altBranchStarts = NIL; ba2f29fRow pattern recognition patch (planner).
1208 106 List *altEndPositions = NIL; ba2f29fRow pattern recognition patch (planner).
1209 - ba2f29fRow pattern recognition patch (planner).
1210 - /* Add alternation start marker */ ba2f29fRow pattern recognition patch (planner).
1211 106 elem = &pat->elements[*idx]; ba2f29fRow pattern recognition patch (planner).
1212 106 memset(elem, 0, sizeof(RPRPatternElement)); ba2f29fRow pattern recognition patch (planner).
1213 106 elem->varId = RPR_VARID_ALT; ba2f29fRow pattern recognition patch (planner).
1214 106 elem->depth = depth; ba2f29fRow pattern recognition patch (planner).
1215 106 elem->min = 1; ba2f29fRow pattern recognition patch (planner).
1216 106 elem->max = 1; ba2f29fRow pattern recognition patch (planner).
1217 106 elem->next = RPR_ELEMIDX_INVALID; ba2f29fRow pattern recognition patch (planner).
1218 106 elem->jump = RPR_ELEMIDX_INVALID; ba2f29fRow pattern recognition patch (planner).
1219 106 (*idx)++; ba2f29fRow pattern recognition patch (planner).
1220 - ba2f29fRow pattern recognition patch (planner).
1221 - /* Fill each alternative */ ba2f29fRow pattern recognition patch (planner).
1222 341 foreach(lc, node->children) ba2f29fRow pattern recognition patch (planner).
1223 - { ba2f29fRow pattern recognition patch (planner).
1224 235 RPRPatternNode *alt = (RPRPatternNode *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
1225 235 int branchStart = *idx; ba2f29fRow pattern recognition patch (planner).
1226 - ba2f29fRow pattern recognition patch (planner).
1227 235 altBranchStarts = lappend_int(altBranchStarts, branchStart); ba2f29fRow pattern recognition patch (planner).
1228 235 fillRPRPattern(alt, pat, idx, depth + 1); ba2f29fRow pattern recognition patch (planner).
1229 235 altEndPositions = lappend_int(altEndPositions, *idx - 1); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1230 235 } ba2f29fRow pattern recognition patch (planner).
1231 - ba2f29fRow pattern recognition patch (planner).
1232 - /* Set jump on first element of each alternative to next alternative */ ba2f29fRow pattern recognition patch (planner).
1233 341 foreach(lc, altBranchStarts) ba2f29fRow pattern recognition patch (planner).
1234 - { ba2f29fRow pattern recognition patch (planner).
1235 235 int firstElemIdx = lfirst_int(lc); ba2f29fRow pattern recognition patch (planner).
1236 - ba2f29fRow pattern recognition patch (planner).
1237 235 if (lnext(altBranchStarts, lc) != NULL) ba2f29fRow pattern recognition patch (planner).
1238 129 pat->elements[firstElemIdx].jump = lfirst_int(lnext(altBranchStarts, lc)); ba2f29fRow pattern recognition patch (planner).
1239 235 } ba2f29fRow pattern recognition patch (planner).
1240 - ba2f29fRow pattern recognition patch (planner).
1241 - /* Set next on last element of each alternative to after the alternation */ ba2f29fRow pattern recognition patch (planner).
1242 - { ba2f29fRow pattern recognition patch (planner).
1243 106 int afterAltIdx = *idx; ba2f29fRow pattern recognition patch (planner).
1244 106 ListCell *lc2 = list_head(altBranchStarts); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1245 - ba2f29fRow pattern recognition patch (planner).
1246 341 foreach(lc, altEndPositions) ba2f29fRow pattern recognition patch (planner).
1247 - { ba2f29fRow pattern recognition patch (planner).
1248 235 int endPos = lfirst_int(lc); ba2f29fRow pattern recognition patch (planner).
1249 235 int branchStart = lfirst_int(lc2); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1250 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1251 235 if (pat->elements[endPos].next != RPR_ELEMIDX_INVALID) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1252 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1253 - /* 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1254 - * An inner ALT already set next on this element. Redirect 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1255 - * all elements in this branch that share the same target to 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1256 - * point to after this ALT instead. 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1257 - */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1258 1 int oldTarget = pat->elements[endPos].next; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1259 1 int j; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1260 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1261 5 for (j = branchStart; j <= endPos; j++) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1262 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1263 4 if (pat->elements[j].next == oldTarget) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1264 2 pat->elements[j].next = afterAltIdx; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1265 4 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1266 1 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1267 - else 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1268 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1269 234 pat->elements[endPos].next = afterAltIdx; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1270 - } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1271 - ba2f29fRow pattern recognition patch (planner).
1272 235 lc2 = lnext(altBranchStarts, lc2); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1273 235 } ba2f29fRow pattern recognition patch (planner).
1274 106 } ba2f29fRow pattern recognition patch (planner).
1275 - ba2f29fRow pattern recognition patch (planner).
1276 106 list_free(altBranchStarts); ba2f29fRow pattern recognition patch (planner).
1277 106 list_free(altEndPositions); ba2f29fRow pattern recognition patch (planner).
1278 106 } ba2f29fRow pattern recognition patch (planner).
fillRPRPattern() lines 1288-1316
Modified Lines Coverage: 15/15 lines (100.0%)
LineHitsSourceCommit
1288 2062 fillRPRPattern(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth depth) ba2f29fRow pattern recognition patch (planner).
1289 - { ba2f29fRow pattern recognition patch (planner).
1290 2062 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
1291 - ba2f29fRow pattern recognition patch (planner).
1292 - /* Pattern nodes from parser are never NULL */ ba2f29fRow pattern recognition patch (planner).
1293 2062 Assert(node != NULL); ba2f29fRow pattern recognition patch (planner).
1294 - ba2f29fRow pattern recognition patch (planner).
1295 2062 switch (node->nodeType) ba2f29fRow pattern recognition patch (planner).
1296 - { ba2f29fRow pattern recognition patch (planner).
1297 - case RPR_PATTERN_SEQ: ba2f29fRow pattern recognition patch (planner).
1298 1306 foreach(lc, node->children) ba2f29fRow pattern recognition patch (planner).
1299 - { ba2f29fRow pattern recognition patch (planner).
1300 1007 fillRPRPattern((RPRPatternNode *) lfirst(lc), pat, idx, depth); ba2f29fRow pattern recognition patch (planner).
1301 1007 } ba2f29fRow pattern recognition patch (planner).
1302 299 break; ba2f29fRow pattern recognition patch (planner).
1303 - ba2f29fRow pattern recognition patch (planner).
1304 - case RPR_PATTERN_VAR: ba2f29fRow pattern recognition patch (planner).
1305 1298 fillRPRPatternVar(node, pat, idx, depth); ba2f29fRow pattern recognition patch (planner).
1306 1298 break; ba2f29fRow pattern recognition patch (planner).
1307 - ba2f29fRow pattern recognition patch (planner).
1308 - case RPR_PATTERN_GROUP: ba2f29fRow pattern recognition patch (planner).
1309 359 fillRPRPatternGroup(node, pat, idx, depth); ba2f29fRow pattern recognition patch (planner).
1310 359 break; ba2f29fRow pattern recognition patch (planner).
1311 - ba2f29fRow pattern recognition patch (planner).
1312 - case RPR_PATTERN_ALT: ba2f29fRow pattern recognition patch (planner).
1313 106 fillRPRPatternAlt(node, pat, idx, depth); ba2f29fRow pattern recognition patch (planner).
1314 106 break; ba2f29fRow pattern recognition patch (planner).
1315 - } ba2f29fRow pattern recognition patch (planner).
1316 2062 } ba2f29fRow pattern recognition patch (planner).
finalizeRPRPattern() lines 1328-1355
Modified Lines Coverage: 19/19 lines (100.0%)
LineHitsSourceCommit
1328 461 finalizeRPRPattern(RPRPattern *result) ba2f29fRow pattern recognition patch (planner).
1329 - { ba2f29fRow pattern recognition patch (planner).
1330 461 int finIdx = result->numElements - 1; ba2f29fRow pattern recognition patch (planner).
1331 461 int i; ba2f29fRow pattern recognition patch (planner).
1332 461 RPRPatternElement *finElem; ba2f29fRow pattern recognition patch (planner).
1333 - ba2f29fRow pattern recognition patch (planner).
1334 - /* Initialize absorption flag */ ba2f29fRow pattern recognition patch (planner).
1335 461 result->isAbsorbable = false; ba2f29fRow pattern recognition patch (planner).
1336 - ba2f29fRow pattern recognition patch (planner).
1337 - /* Set up next pointers for elements that don't have one */ ba2f29fRow pattern recognition patch (planner).
1338 2583 for (i = 0; i < finIdx; i++) ba2f29fRow pattern recognition patch (planner).
1339 - { ba2f29fRow pattern recognition patch (planner).
1340 2122 RPRPatternElement *elem = &result->elements[i]; ba2f29fRow pattern recognition patch (planner).
1341 - ba2f29fRow pattern recognition patch (planner).
1342 2122 if (elem->next == RPR_ELEMIDX_INVALID) ba2f29fRow pattern recognition patch (planner).
1343 1888 elem->next = (i < finIdx - 1) ? i + 1 : finIdx; ba2f29fRow pattern recognition patch (planner).
1344 2122 } ba2f29fRow pattern recognition patch (planner).
1345 - ba2f29fRow pattern recognition patch (planner).
1346 - /* Add FIN marker at the end */ ba2f29fRow pattern recognition patch (planner).
1347 461 finElem = &result->elements[finIdx]; ba2f29fRow pattern recognition patch (planner).
1348 461 memset(finElem, 0, sizeof(RPRPatternElement)); ba2f29fRow pattern recognition patch (planner).
1349 461 finElem->varId = RPR_VARID_FIN; ba2f29fRow pattern recognition patch (planner).
1350 461 finElem->depth = 0; ba2f29fRow pattern recognition patch (planner).
1351 461 finElem->min = 1; ba2f29fRow pattern recognition patch (planner).
1352 461 finElem->max = 1; ba2f29fRow pattern recognition patch (planner).
1353 461 finElem->next = RPR_ELEMIDX_INVALID; ba2f29fRow pattern recognition patch (planner).
1354 461 finElem->jump = RPR_ELEMIDX_INVALID; ba2f29fRow pattern recognition patch (planner).
1355 461 } ba2f29fRow pattern recognition patch (planner).
isUnboundedStart() lines 1465-1511
Modified Lines Coverage: 25/25 lines (100.0%)
LineHitsSourceCommit
1465 457 isUnboundedStart(RPRPattern *pattern, RPRElemIdx idx) 9d2796cReview NFA executor and add comprehensive runtime tests
1466 - { ba2f29fRow pattern recognition patch (planner).
1467 457 RPRPatternElement *elem = &pattern->elements[idx]; ba2f29fRow pattern recognition patch (planner).
1468 457 RPRDepth startDepth = elem->depth; ba2f29fRow pattern recognition patch (planner).
1469 457 RPRPatternElement *nextElem; ba2f29fRow pattern recognition patch (planner).
1470 457 RPRPatternElement *e; ba2f29fRow pattern recognition patch (planner).
1471 - ba2f29fRow pattern recognition patch (planner).
1472 - /* Case 1: Simple unbounded VAR at start (greedy only) */ 9d2796cReview NFA executor and add comprehensive runtime tests
1473 457 if (RPRElemIsVar(elem) && elem->max == RPR_QUANTITY_INF && 9d2796cReview NFA executor and add comprehensive runtime tests
1474 175 !RPRElemIsReluctant(elem)) 9d2796cReview NFA executor and add comprehensive runtime tests
1475 - { 9d2796cReview NFA executor and add comprehensive runtime tests
1476 - /* Set both flags on first element */ 9d2796cReview NFA executor and add comprehensive runtime tests
1477 175 elem->flags |= RPR_ELEM_ABSORBABLE_BRANCH | RPR_ELEM_ABSORBABLE; 9d2796cReview NFA executor and add comprehensive runtime tests
1478 175 return true; 9d2796cReview NFA executor and add comprehensive runtime tests
1479 - } 9d2796cReview NFA executor and add comprehensive runtime tests
1480 - 9d2796cReview NFA executor and add comprehensive runtime tests
1481 - /* ba2f29fRow pattern recognition patch (planner).
1482 - * Case 2: Unbounded GROUP - traverse siblings at startDepth and check if 9d2796cReview NFA executor and add comprehensive runtime tests
1483 - * they're all simple {1,1} VARs, then check if END at startDepth - 1 is 9d2796cReview NFA executor and add comprehensive runtime tests
1484 - * unbounded greedy. 9d2796cReview NFA executor and add comprehensive runtime tests
1485 - */ ba2f29fRow pattern recognition patch (planner).
1486 935 for (e = elem; e->depth == startDepth; e = nextElem) 9d2796cReview NFA executor and add comprehensive runtime tests
1487 - { ba2f29fRow pattern recognition patch (planner).
1488 - /* Must be simple {1,1} VAR */ 9d2796cReview NFA executor and add comprehensive runtime tests
1489 783 if (!RPRElemIsVar(e) || e->min != 1 || e->max != 1) 9d2796cReview NFA executor and add comprehensive runtime tests
1490 130 return false; 9d2796cReview NFA executor and add comprehensive runtime tests
1491 - ba2f29fRow pattern recognition patch (planner).
1492 653 Assert(e->next != RPR_ELEMIDX_INVALID); ba2f29fRow pattern recognition patch (planner).
1493 653 nextElem = &pattern->elements[e->next]; ba2f29fRow pattern recognition patch (planner).
1494 653 } ba2f29fRow pattern recognition patch (planner).
1495 - ba2f29fRow pattern recognition patch (planner).
1496 - /* Now e should be END at startDepth - 1 */ 9d2796cReview NFA executor and add comprehensive runtime tests
1497 179 if (e->depth == startDepth - 1 && 9d2796cReview NFA executor and add comprehensive runtime tests
1498 102 RPRElemIsEnd(e) && e->max == RPR_QUANTITY_INF && 9d2796cReview NFA executor and add comprehensive runtime tests
1499 27 !RPRElemIsReluctant(e)) 9d2796cReview NFA executor and add comprehensive runtime tests
1500 - { ba2f29fRow pattern recognition patch (planner).
1501 27 Assert(e->jump == idx); /* END points back to first child */ 9d2796cReview NFA executor and add comprehensive runtime tests
1502 - 9d2796cReview NFA executor and add comprehensive runtime tests
1503 - /* Set ABSORBABLE_BRANCH on all children, ABSORBABLE on END only */ 9d2796cReview NFA executor and add comprehensive runtime tests
1504 83 for (e = elem; !RPRElemIsEnd(e); e = &pattern->elements[e->next]) 9d2796cReview NFA executor and add comprehensive runtime tests
1505 56 e->flags |= RPR_ELEM_ABSORBABLE_BRANCH; 9d2796cReview NFA executor and add comprehensive runtime tests
1506 27 e->flags |= RPR_ELEM_ABSORBABLE_BRANCH | RPR_ELEM_ABSORBABLE; 9d2796cReview NFA executor and add comprehensive runtime tests
1507 27 return true; ba2f29fRow pattern recognition patch (planner).
1508 - } ba2f29fRow pattern recognition patch (planner).
1509 - ba2f29fRow pattern recognition patch (planner).
1510 125 return false; ba2f29fRow pattern recognition patch (planner).
1511 457 } ba2f29fRow pattern recognition patch (planner).
computeAbsorbabilityRecursive() lines 1527-1584
Modified Lines Coverage: 30/30 lines (100.0%)
LineHitsSourceCommit
1527 858 computeAbsorbabilityRecursive(RPRPattern *pattern, RPRElemIdx startIdx, ba2f29fRow pattern recognition patch (planner).
1528 - bool *hasAbsorbable) 9d2796cReview NFA executor and add comprehensive runtime tests
1529 - { ba2f29fRow pattern recognition patch (planner).
1530 858 RPRPatternElement *elem = &pattern->elements[startIdx]; ba2f29fRow pattern recognition patch (planner).
1531 - ba2f29fRow pattern recognition patch (planner).
1532 858 if (RPRElemIsAlt(elem)) ba2f29fRow pattern recognition patch (planner).
1533 - { ba2f29fRow pattern recognition patch (planner).
1534 - /* ALT: recursively check each branch */ ba2f29fRow pattern recognition patch (planner).
1535 68 RPRElemIdx branchIdx = elem->next; ba2f29fRow pattern recognition patch (planner).
1536 68 RPRPatternElement *branchFirst; ba2f29fRow pattern recognition patch (planner).
1537 68 bool branchAbsorbable; ba2f29fRow pattern recognition patch (planner).
1538 - ba2f29fRow pattern recognition patch (planner).
1539 221 while (branchIdx != RPR_ELEMIDX_INVALID) ba2f29fRow pattern recognition patch (planner).
1540 - { ba2f29fRow pattern recognition patch (planner).
1541 154 branchAbsorbable = false; ba2f29fRow pattern recognition patch (planner).
1542 - ba2f29fRow pattern recognition patch (planner).
1543 154 Assert(branchIdx < pattern->numElements); ba2f29fRow pattern recognition patch (planner).
1544 154 branchFirst = &pattern->elements[branchIdx]; ba2f29fRow pattern recognition patch (planner).
1545 - ba2f29fRow pattern recognition patch (planner).
1546 - /* Stop if element is outside ALT scope (not a branch) */ 9d2796cReview NFA executor and add comprehensive runtime tests
1547 154 if (branchFirst->depth <= elem->depth) 9d2796cReview NFA executor and add comprehensive runtime tests
1548 1 break; 9d2796cReview NFA executor and add comprehensive runtime tests
1549 - 9d2796cReview NFA executor and add comprehensive runtime tests
1550 - /* Recursively check this branch */ 9d2796cReview NFA executor and add comprehensive runtime tests
1551 153 computeAbsorbabilityRecursive(pattern, branchIdx, &branchAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
1552 153 if (branchAbsorbable) ba2f29fRow pattern recognition patch (planner).
1553 - { ba2f29fRow pattern recognition patch (planner).
1554 30 *hasAbsorbable = true; ba2f29fRow pattern recognition patch (planner).
1555 30 } ba2f29fRow pattern recognition patch (planner).
1556 - ba2f29fRow pattern recognition patch (planner).
1557 153 branchIdx = branchFirst->jump; ba2f29fRow pattern recognition patch (planner).
1558 - } ba2f29fRow pattern recognition patch (planner).
1559 - ba2f29fRow pattern recognition patch (planner).
1560 - /* Mark ALT element if any branch is absorbable */ ba2f29fRow pattern recognition patch (planner).
1561 68 if (*hasAbsorbable) ba2f29fRow pattern recognition patch (planner).
1562 21 elem->flags |= RPR_ELEM_ABSORBABLE_BRANCH; ba2f29fRow pattern recognition patch (planner).
1563 68 } ba2f29fRow pattern recognition patch (planner).
1564 790 else if (RPRElemIsBegin(elem)) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1565 - { 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1566 - /* BEGIN: skip to first child and check that */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1567 333 computeAbsorbabilityRecursive(pattern, elem->next, hasAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
1568 - 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1569 - /* Mark BEGIN element if contents are absorbable */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1570 333 if (*hasAbsorbable) 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1571 37 elem->flags |= RPR_ELEM_ABSORBABLE_BRANCH; 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1572 333 } 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1573 - else ba2f29fRow pattern recognition patch (planner).
1574 - { ba2f29fRow pattern recognition patch (planner).
1575 - /* Should never reach END - structural invariant of pattern AST */ 9d2796cReview NFA executor and add comprehensive runtime tests
1576 457 Assert(!RPRElemIsEnd(elem)); 9d2796cReview NFA executor and add comprehensive runtime tests
1577 - 9d2796cReview NFA executor and add comprehensive runtime tests
1578 - /* Non-ALT, non-BEGIN: check if unbounded start */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1579 457 if (isUnboundedStart(pattern, startIdx)) 9d2796cReview NFA executor and add comprehensive runtime tests
1580 - { ba2f29fRow pattern recognition patch (planner).
1581 202 *hasAbsorbable = true; ba2f29fRow pattern recognition patch (planner).
1582 202 } ba2f29fRow pattern recognition patch (planner).
1583 - } ba2f29fRow pattern recognition patch (planner).
1584 858 } ba2f29fRow pattern recognition patch (planner).
computeAbsorbability() lines 1616-1626
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
1616 372 computeAbsorbability(RPRPattern *pattern) ba2f29fRow pattern recognition patch (planner).
1617 - { ba2f29fRow pattern recognition patch (planner).
1618 372 bool hasAbsorbable = false; ba2f29fRow pattern recognition patch (planner).
1619 - ba2f29fRow pattern recognition patch (planner).
1620 - /* Parser always produces at least one element + FIN */ ba2f29fRow pattern recognition patch (planner).
1621 372 Assert(pattern->numElements >= 2); ba2f29fRow pattern recognition patch (planner).
1622 - ba2f29fRow pattern recognition patch (planner).
1623 - /* Start recursion from first element */ 9d2796cReview NFA executor and add comprehensive runtime tests
1624 372 computeAbsorbabilityRecursive(pattern, 0, &hasAbsorbable); 9d2796cReview NFA executor and add comprehensive runtime tests
1625 372 pattern->isAbsorbable = hasAbsorbable; ba2f29fRow pattern recognition patch (planner).
1626 372 } ba2f29fRow pattern recognition patch (planner).
collectPatternVariablesRecursive() lines 1633-1661
Modified Lines Coverage: 16/16 lines (100.0%)
LineHitsSourceCommit
1633 2647 collectPatternVariablesRecursive(RPRPatternNode *node, List **varNames) ba2f29fRow pattern recognition patch (planner).
1634 - { ba2f29fRow pattern recognition patch (planner).
1635 2647 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
1636 - ba2f29fRow pattern recognition patch (planner).
1637 2647 Assert(node != NULL); ba2f29fRow pattern recognition patch (planner).
1638 - ba2f29fRow pattern recognition patch (planner).
1639 2647 switch (node->nodeType) ba2f29fRow pattern recognition patch (planner).
1640 - { ba2f29fRow pattern recognition patch (planner).
1641 - case RPR_PATTERN_VAR: ba2f29fRow pattern recognition patch (planner).
1642 - /* Add variable if not already in list */ ba2f29fRow pattern recognition patch (planner).
1643 34074 foreach(lc, *varNames) ba2f29fRow pattern recognition patch (planner).
1644 - { ba2f29fRow pattern recognition patch (planner).
1645 32652 if (strcmp(strVal(lfirst(lc)), node->varName) == 0) ba2f29fRow pattern recognition patch (planner).
1646 172 return; /* Already collected */ ba2f29fRow pattern recognition patch (planner).
1647 32480 } ba2f29fRow pattern recognition patch (planner).
1648 1250 *varNames = lappend(*varNames, makeString(pstrdup(node->varName))); ba2f29fRow pattern recognition patch (planner).
1649 1250 break; ba2f29fRow pattern recognition patch (planner).
1650 - ba2f29fRow pattern recognition patch (planner).
1651 - case RPR_PATTERN_SEQ: ba2f29fRow pattern recognition patch (planner).
1652 - case RPR_PATTERN_ALT: ba2f29fRow pattern recognition patch (planner).
1653 - case RPR_PATTERN_GROUP: ba2f29fRow pattern recognition patch (planner).
1654 3410 foreach(lc, node->children) ba2f29fRow pattern recognition patch (planner).
1655 - { ba2f29fRow pattern recognition patch (planner).
1656 4370 collectPatternVariablesRecursive((RPRPatternNode *) lfirst(lc), ba2f29fRow pattern recognition patch (planner).
1657 2185 varNames); ba2f29fRow pattern recognition patch (planner).
1658 2185 } ba2f29fRow pattern recognition patch (planner).
1659 1225 break; ba2f29fRow pattern recognition patch (planner).
1660 - } ba2f29fRow pattern recognition patch (planner).
1661 2647 } ba2f29fRow pattern recognition patch (planner).
collectPatternVariables() lines 1671-1680
Modified Lines Coverage: 6/6 lines (100.0%)
LineHitsSourceCommit
1671 462 collectPatternVariables(RPRPatternNode *pattern) ba2f29fRow pattern recognition patch (planner).
1672 - { ba2f29fRow pattern recognition patch (planner).
1673 462 List *varNames = NIL; ba2f29fRow pattern recognition patch (planner).
1674 - ba2f29fRow pattern recognition patch (planner).
1675 - /* Caller ensures pattern is not NULL */ 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1676 462 Assert(pattern != NULL); 6be1666Fix RPR pattern compilation crash and refactor EXPLAIN deparse
1677 - ba2f29fRow pattern recognition patch (planner).
1678 462 collectPatternVariablesRecursive(pattern, &varNames); ba2f29fRow pattern recognition patch (planner).
1679 924 return varNames; ba2f29fRow pattern recognition patch (planner).
1680 462 } ba2f29fRow pattern recognition patch (planner).
filterDefineClause() lines 1693-1727
Modified Lines Coverage: 20/20 lines (100.0%)
LineHitsSourceCommit
1693 462 filterDefineClause(List *defineClause, List *patternVars, ba2f29fRow pattern recognition patch (planner).
1694 - List **defineVariableList) ba2f29fRow pattern recognition patch (planner).
1695 - { ba2f29fRow pattern recognition patch (planner).
1696 462 List *filteredDefineClause = NIL; ba2f29fRow pattern recognition patch (planner).
1697 462 ListCell *lc; ba2f29fRow pattern recognition patch (planner).
1698 462 ListCell *lc2; ba2f29fRow pattern recognition patch (planner).
1699 - ba2f29fRow pattern recognition patch (planner).
1700 462 *defineVariableList = NIL; ba2f29fRow pattern recognition patch (planner).
1701 - ba2f29fRow pattern recognition patch (planner).
1702 - /* Filter defineClause: keep only variables used in PATTERN */ ba2f29fRow pattern recognition patch (planner).
1703 1961 foreach(lc, defineClause) ba2f29fRow pattern recognition patch (planner).
1704 - { ba2f29fRow pattern recognition patch (planner).
1705 1499 TargetEntry *te = (TargetEntry *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
1706 - ba2f29fRow pattern recognition patch (planner).
1707 36096 foreach(lc2, patternVars) ba2f29fRow pattern recognition patch (planner).
1708 - { ba2f29fRow pattern recognition patch (planner).
1709 34597 if (strcmp(strVal(lfirst(lc2)), te->resname) == 0) ba2f29fRow pattern recognition patch (planner).
1710 - { ba2f29fRow pattern recognition patch (planner).
1711 1244 filteredDefineClause = lappend(filteredDefineClause, te); ba2f29fRow pattern recognition patch (planner).
1712 1244 break; ba2f29fRow pattern recognition patch (planner).
1713 - } ba2f29fRow pattern recognition patch (planner).
1714 33353 } ba2f29fRow pattern recognition patch (planner).
1715 1499 } ba2f29fRow pattern recognition patch (planner).
1716 - ba2f29fRow pattern recognition patch (planner).
1717 - /* Build defineVariableList from filtered defineClause */ ba2f29fRow pattern recognition patch (planner).
1718 1706 foreach(lc, filteredDefineClause) ba2f29fRow pattern recognition patch (planner).
1719 - { ba2f29fRow pattern recognition patch (planner).
1720 1244 TargetEntry *te = (TargetEntry *) lfirst(lc); ba2f29fRow pattern recognition patch (planner).
1721 - ba2f29fRow pattern recognition patch (planner).
1722 2488 *defineVariableList = lappend(*defineVariableList, ba2f29fRow pattern recognition patch (planner).
1723 1244 makeString(pstrdup(te->resname))); ba2f29fRow pattern recognition patch (planner).
1724 1244 } ba2f29fRow pattern recognition patch (planner).
1725 - ba2f29fRow pattern recognition patch (planner).
1726 924 return filteredDefineClause; ba2f29fRow pattern recognition patch (planner).
1727 462 } ba2f29fRow pattern recognition patch (planner).
buildRPRPattern() lines 1744-1806
Modified Lines Coverage: 24/24 lines (100.0%)
LineHitsSourceCommit
1744 462 buildRPRPattern(RPRPatternNode *pattern, List *defineVariableList, ba2f29fRow pattern recognition patch (planner).
1745 - RPSkipTo rpSkipTo, int frameOptions) ba2f29fRow pattern recognition patch (planner).
1746 - { ba2f29fRow pattern recognition patch (planner).
1747 462 RPRPattern *result; ba2f29fRow pattern recognition patch (planner).
1748 462 RPRPatternNode *optimized; ba2f29fRow pattern recognition patch (planner).
1749 462 char *varNamesStack[RPR_VARID_MAX]; ba2f29fRow pattern recognition patch (planner).
1750 462 int numVars; ba2f29fRow pattern recognition patch (planner).
1751 462 int numElements; ba2f29fRow pattern recognition patch (planner).
1752 462 RPRDepth maxDepth; ba2f29fRow pattern recognition patch (planner).
1753 462 int idx; ba2f29fRow pattern recognition patch (planner).
1754 462 bool hasLimitedFrame; ba2f29fRow pattern recognition patch (planner).
1755 - ba2f29fRow pattern recognition patch (planner).
1756 - /* Caller must check for NULL pattern before calling */ ba2f29fRow pattern recognition patch (planner).
1757 462 Assert(pattern != NULL); ba2f29fRow pattern recognition patch (planner).
1758 - ba2f29fRow pattern recognition patch (planner).
1759 - /* Optimize the pattern tree */ ba2f29fRow pattern recognition patch (planner).
1760 462 optimized = optimizeRPRPattern(copyObject(pattern)); ba2f29fRow pattern recognition patch (planner).
1761 - ba2f29fRow pattern recognition patch (planner).
1762 - /* Collect variable names from DEFINE clause */ ba2f29fRow pattern recognition patch (planner).
1763 462 numVars = collectDefineVariables(defineVariableList, varNamesStack); ba2f29fRow pattern recognition patch (planner).
1764 - ba2f29fRow pattern recognition patch (planner).
1765 - /* Scan pattern: collect variables, count elements, validate limits */ ba2f29fRow pattern recognition patch (planner).
1766 462 scanRPRPattern(optimized, varNamesStack, &numVars, &numElements, &maxDepth); ba2f29fRow pattern recognition patch (planner).
1767 - ba2f29fRow pattern recognition patch (planner).
1768 - /* Allocate result structure */ ba2f29fRow pattern recognition patch (planner).
1769 462 result = allocateRPRPattern(numVars, numElements, maxDepth, varNamesStack); ba2f29fRow pattern recognition patch (planner).
1770 - ba2f29fRow pattern recognition patch (planner).
1771 - /* Fill elements (pass 2) */ ba2f29fRow pattern recognition patch (planner).
1772 462 idx = 0; ba2f29fRow pattern recognition patch (planner).
1773 462 fillRPRPattern(optimized, result, &idx, 0); ba2f29fRow pattern recognition patch (planner).
1774 - ba2f29fRow pattern recognition patch (planner).
1775 - /* Finalize: set up next pointers, flags, and add FIN marker */ ba2f29fRow pattern recognition patch (planner).
1776 462 finalizeRPRPattern(result); ba2f29fRow pattern recognition patch (planner).
1777 - ba2f29fRow pattern recognition patch (planner).
1778 - /* ba2f29fRow pattern recognition patch (planner).
1779 - * Compute context absorption eligibility. Absorption requires both ba2f29fRow pattern recognition patch (planner).
1780 - * structural absorbability and runtime conditions. Check runtime ba2f29fRow pattern recognition patch (planner).
1781 - * conditions first to avoid unnecessary pattern analysis. ba2f29fRow pattern recognition patch (planner).
1782 - * ba2f29fRow pattern recognition patch (planner).
1783 - * Runtime conditions for absorption: ba2f29fRow pattern recognition patch (planner).
1784 - * ba2f29fRow pattern recognition patch (planner).
1785 - * 1. SKIP TO PAST LAST ROW required (not SKIP TO NEXT ROW): With NEXT ba2f29fRow pattern recognition patch (planner).
1786 - * ROW, after each match the search resumes from the next row, so contexts ba2f29fRow pattern recognition patch (planner).
1787 - * are immediately discarded. No redundant contexts accumulate, making ba2f29fRow pattern recognition patch (planner).
1788 - * absorption unnecessary. ba2f29fRow pattern recognition patch (planner).
1789 - * ba2f29fRow pattern recognition patch (planner).
1790 - * 2. Unbounded frame end required (not ROWS with bounded end): With a ba2f29fRow pattern recognition patch (planner).
1791 - * bounded frame (e.g., ROWS BETWEEN CURRENT ROW AND 10 FOLLOWING), ba2f29fRow pattern recognition patch (planner).
1792 - * matches may be truncated at frame boundaries. This changes the ba2f29fRow pattern recognition patch (planner).
1793 - * absorption semantics - older contexts don't necessarily produce longer ba2f29fRow pattern recognition patch (planner).
1794 - * matches when frame limits apply differently to each context. ba2f29fRow pattern recognition patch (planner).
1795 - */ ba2f29fRow pattern recognition patch (planner).
1796 923 hasLimitedFrame = (frameOptions & FRAMEOPTION_ROWS) && ba2f29fRow pattern recognition patch (planner).
1797 461 !(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING); ba2f29fRow pattern recognition patch (planner).
1798 - ba2f29fRow pattern recognition patch (planner).
1799 462 if (rpSkipTo == ST_PAST_LAST_ROW && !hasLimitedFrame) ba2f29fRow pattern recognition patch (planner).
1800 - { ba2f29fRow pattern recognition patch (planner).
1801 - /* Runtime conditions met - check structural absorbability */ ba2f29fRow pattern recognition patch (planner).
1802 372 computeAbsorbability(result); ba2f29fRow pattern recognition patch (planner).
1803 372 } ba2f29fRow pattern recognition patch (planner).
1804 - ba2f29fRow pattern recognition patch (planner).
1805 924 return result; ba2f29fRow pattern recognition patch (planner).
1806 462 } ba2f29fRow pattern recognition patch (planner).