← Back to Overview

src/backend/optimizer/plan/createplan.c

Coverage: 126/127 lines (99.2%)
Total Lines
127
modified
Covered
126
99.2%
Uncovered
1
0.8%
Keyboard navigation
dependency() lines 2475-2494
Modified Lines Coverage: 0/0 lines (0.0%)
LineHitsSourceCommit
2475 - * - per-variable match_start dependency (variables containing FIRST, 7521a30Row pattern recognition patch (planner).
2476 - * LAST-with-offset, or compound PREV_FIRST/NEXT_FIRST/PREV_LAST/ 7521a30Row pattern recognition patch (planner).
2477 - * NEXT_LAST-with-offset require per-context re-evaluation) 7521a30Row pattern recognition patch (planner).
2478 - * 7521a30Row pattern recognition patch (planner).
2479 - * The driver sets curVarIdx to the index of the variable being walked 7521a30Row pattern recognition patch (planner).
2480 - * before each invocation; the walker uses it to populate matchStartDependent. 7521a30Row pattern recognition patch (planner).
2481 - */ 7521a30Row pattern recognition patch (planner).
2482 - typedef struct DefineMetadataContext 7521a30Row pattern recognition patch (planner).
2483 - { 7521a30Row pattern recognition patch (planner).
2484 - int64 maxOffset; /* max PREV/LAST backward offset (>= 0) */ 7521a30Row pattern recognition patch (planner).
2485 - bool maxNeedsEval; /* non-constant PREV/LAST offset found */ 7521a30Row pattern recognition patch (planner).
2486 - bool maxOverflow; /* constant offset overflow detected */ 7521a30Row pattern recognition patch (planner).
2487 - int64 firstOffset; /* min FIRST offset (may be negative for 7521a30Row pattern recognition patch (planner).
2488 - * PREV_FIRST) */ 7521a30Row pattern recognition patch (planner).
2489 - bool hasFirst; /* any FIRST node found */ 7521a30Row pattern recognition patch (planner).
2490 - bool firstNeedsEval; /* non-constant FIRST offset found */ 7521a30Row pattern recognition patch (planner).
2491 - int curVarIdx; /* DEFINE variable currently being walked */ 7521a30Row pattern recognition patch (planner).
2492 - Bitmapset *matchStartDependent; /* variables that depend on 7521a30Row pattern recognition patch (planner).
2493 - * match_start */ 7521a30Row pattern recognition patch (planner).
2494 - } DefineMetadataContext; 7521a30Row pattern recognition patch (planner).
extract_const_offset() lines 2502-2526
Modified Lines Coverage: 12/12 lines (100.0%)
LineHitsSourceCommit
2502 1320 extract_const_offset(Expr *expr, int64 defaultOffset, int64 *result) 7521a30Row pattern recognition patch (planner).
2503 - { 7521a30Row pattern recognition patch (planner).
2504 1320 if (expr == NULL) 7521a30Row pattern recognition patch (planner).
2505 - { 7521a30Row pattern recognition patch (planner).
2506 885 *result = defaultOffset; 7521a30Row pattern recognition patch (planner).
2507 885 return true; 7521a30Row pattern recognition patch (planner).
2508 - } 7521a30Row pattern recognition patch (planner).
2509 - 7521a30Row pattern recognition patch (planner).
2510 435 if (IsA(expr, Const)) 7521a30Row pattern recognition patch (planner).
2511 - { 7521a30Row pattern recognition patch (planner).
2512 415 Const *c = (Const *) expr; 7521a30Row pattern recognition patch (planner).
2513 - 7521a30Row pattern recognition patch (planner).
2514 415 if (c->constisnull) 7521a30Row pattern recognition patch (planner).
2515 40 *result = 0; /* runtime error; safe placeholder */ 7521a30Row pattern recognition patch (planner).
2516 - else 7521a30Row pattern recognition patch (planner).
2517 - { 7521a30Row pattern recognition patch (planner).
2518 375 *result = DatumGetInt64(c->constvalue); 7521a30Row pattern recognition patch (planner).
2519 375 if (*result < 0) 7521a30Row pattern recognition patch (planner).
2520 35 *result = 0; /* runtime error; safe placeholder */ 7521a30Row pattern recognition patch (planner).
2521 - } 7521a30Row pattern recognition patch (planner).
2522 415 return true; 7521a30Row pattern recognition patch (planner).
2523 - } 7521a30Row pattern recognition patch (planner).
2524 - 7521a30Row pattern recognition patch (planner).
2525 - return false; /* non-constant */ 7521a30Row pattern recognition patch (planner).
2526 - } 7521a30Row pattern recognition patch (planner).
visit_nav_plan() lines 2555-2711
Modified Lines Coverage: 56/57 lines (98.2%)
LineHitsSourceCommit
2555 1275 visit_nav_plan(NavTraversal *t, RPRNavExpr *nav) 7521a30Row pattern recognition patch (planner).
2556 - { 7521a30Row pattern recognition patch (planner).
2557 1275 DefineMetadataContext *context = (DefineMetadataContext *) t->data; 7521a30Row pattern recognition patch (planner).
2558 - 7521a30Row pattern recognition patch (planner).
2559 - /* 7521a30Row pattern recognition patch (planner).
2560 - * Parser guarantee: by the time the planner sees a DEFINE expression, 7521a30Row pattern recognition patch (planner).
2561 - * compound nesting has been flattened into a single RPRNavExpr and any 7521a30Row pattern recognition patch (planner).
2562 - * other RPRNavExpr nesting has been rejected. So nav's direct child 7521a30Row pattern recognition patch (planner).
2563 - * fields are not themselves RPRNavExpr nodes, and outer-kind dispatch 7521a30Row pattern recognition patch (planner).
2564 - * below is sufficient. 7521a30Row pattern recognition patch (planner).
2565 - */ 7521a30Row pattern recognition patch (planner).
2566 1275 Assert(nav->arg == NULL || !IsA(nav->arg, RPRNavExpr)); 7521a30Row pattern recognition patch (planner).
2567 1275 Assert(nav->offset_arg == NULL || !IsA(nav->offset_arg, RPRNavExpr)); 7521a30Row pattern recognition patch (planner).
2568 1275 Assert(nav->compound_offset_arg == NULL || 7521a30Row pattern recognition patch (planner).
2569 - !IsA(nav->compound_offset_arg, RPRNavExpr)); 7521a30Row pattern recognition patch (planner).
2570 - 7521a30Row pattern recognition patch (planner).
2571 - /* 7521a30Row pattern recognition patch (planner).
2572 - * Simple PREV(v, N) and LAST(v, N): backward reach from currentpos. LAST 7521a30Row pattern recognition patch (planner).
2573 - * without offset = currentpos, no backward reach. NEXT: forward only, 7521a30Row pattern recognition patch (planner).
2574 - * irrelevant for trim. 7521a30Row pattern recognition patch (planner).
2575 - */ 7521a30Row pattern recognition patch (planner).
2576 1275 if (nav->kind == RPR_NAV_PREV || 7521a30Row pattern recognition patch (planner).
2577 65 (nav->kind == RPR_NAV_LAST && nav->offset_arg != NULL)) 7521a30Row pattern recognition patch (planner).
2578 - { 7521a30Row pattern recognition patch (planner).
2579 940 if (!context->maxNeedsEval) 7521a30Row pattern recognition patch (planner).
2580 - { 7521a30Row pattern recognition patch (planner).
2581 940 int64 offset; 7521a30Row pattern recognition patch (planner).
2582 - 7521a30Row pattern recognition patch (planner).
2583 - /* 7521a30Row pattern recognition patch (planner).
2584 - * default 1 is for PREV; the guarded LAST sub-case never uses it. 7521a30Row pattern recognition patch (planner).
2585 - */ 7521a30Row pattern recognition patch (planner).
2586 940 if (extract_const_offset(nav->offset_arg, 1, &offset)) 7521a30Row pattern recognition patch (planner).
2587 930 context->maxOffset = Max(context->maxOffset, offset); 7521a30Row pattern recognition patch (planner).
2588 - else 7521a30Row pattern recognition patch (planner).
2589 10 context->maxNeedsEval = true; 7521a30Row pattern recognition patch (planner).
2590 - } 7521a30Row pattern recognition patch (planner).
2591 - } 7521a30Row pattern recognition patch (planner).
2592 - 7521a30Row pattern recognition patch (planner).
2593 - /* 7521a30Row pattern recognition patch (planner).
2594 - * Simple FIRST(v, N): forward reach from match_start. Smaller N means 7521a30Row pattern recognition patch (planner).
2595 - * older rows needed. 7521a30Row pattern recognition patch (planner).
2596 - */ 7521a30Row pattern recognition patch (planner).
2597 1275 if (nav->kind == RPR_NAV_FIRST) 7521a30Row pattern recognition patch (planner).
2598 - { 7521a30Row pattern recognition patch (planner).
2599 60 context->hasFirst = true; 7521a30Row pattern recognition patch (planner).
2600 - 7521a30Row pattern recognition patch (planner).
2601 60 if (!context->firstNeedsEval) 7521a30Row pattern recognition patch (planner).
2602 - { 7521a30Row pattern recognition patch (planner).
2603 60 int64 offset; 7521a30Row pattern recognition patch (planner).
2604 - 7521a30Row pattern recognition patch (planner).
2605 60 if (extract_const_offset(nav->offset_arg, 0, &offset)) 7521a30Row pattern recognition patch (planner).
2606 60 context->firstOffset = Min(context->firstOffset, offset); 7521a30Row pattern recognition patch (planner).
2607 - else 7521a30Row pattern recognition patch (planner).
2608 0 context->firstNeedsEval = true; 7521a30Row pattern recognition patch (planner).
ReachableTestable · confidence high · visit_nav_plan @2608
How to test
Add to src/test/regress/sql/rpr.sql near the FIRST offset tests (rpr_nav has columns id int, val int):

SET plan_cache_mode = force_generic_plan;
PREPARE test_first_offset(int8) AS
SELECT id, val, first_value(id) OVER w AS mf, count(*) OVER w AS cnt
FROM rpr_nav
WINDOW w AS (
ORDER BY id
ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
AFTER MATCH SKIP PAST LAST ROW
PATTERN (A B+)
DEFINE A AS TRUE, B AS val = FIRST(val, $1)
);
EXECUTE test_first_offset(1);
DEALLOCATE test_first_offset;
RESET plan_cache_mode;

The `SET plan_cache_mode = force_generic_plan;
` is the load-bearing addition the original proposal omits: without it the planner const-folds $1 and executes line 2606 instead of 2608. With it, $1 remains a Param, extract_const_offset returns false, and line 2608 (context->firstNeedsEval = true) is driven.
Verified via gcov on the coverage build: 2608 count went from ##### to 1. Expected output for
EXECUTE(1) under the generic plan: rows (1,10,1,2),(2,20,,0),(3,30,3,2),(4,10,,0),(5,50,5,2),(6,10,,0) -- identical to the custom-plan result since the runtime offset value is the same;
capture it in rpr.out.
Verdict
Line 2608 (context->firstNeedsEval = true) is genuinely reachable: it is the else-branch of `if (extract_const_offset(nav->offset_arg, 0, &offset))` in the RPR_NAV_FIRST case, taken when a simple FIRST(v, N) has a non-Const offset_arg.
I confirmed reachability empirically on a coverage-instrumented RPR build.
HOWEVER, the proposed test as written does NOT cover line 2608. I built+installed the RPR source into a temp datadir, ran the exact proposed
PREPARE/EXECUTE on a -DCOVERAGE build, stopped the server to flush gcda, and ran gcov: line 2606 (the if-branch) showed count 1 while line 2608 stayed ##### (uncovered).
Reason: by default PostgreSQL builds a CUSTOM plan for the first ~5 executions of a prepared statement, substituting the actual
EXECUTE argument for $1 and const-folding it to a Const, so extract_const_offset returns TRUE and the if-branch (2606) runs, not the else (2608).
To force the Param to survive planning as a Param I added `SET plan_cache_mode = force_generic_plan;
` before
EXECUTE and re-ran with cleared gcda: gcov then showed line 2608 count 1 and line 2606 ##### -- proving the else-branch fires only under a generic plan.
So the claim that $1 is a Param at planner time is only true with a generic plan;
the unqualified custom-plan path const-folds it.
The existing PREV($1)/compound PREV(FIRST(val,$1),$2) tests (rpr.sql:888,1260) very likely have the same custom-plan issue for their respective else-branches (2589/2643), but those lines were already covered by other const tests/paths and are out of scope here.
2609 - } 7521a30Row pattern recognition patch (planner).
2610 - } 7521a30Row pattern recognition patch (planner).
2611 - 7521a30Row pattern recognition patch (planner).
2612 - /* 7521a30Row pattern recognition patch (planner).
2613 - * Compound PREV_LAST / NEXT_LAST: base = currentpos. PREV_LAST(v, N, M): 7521a30Row pattern recognition patch (planner).
2614 - * target = currentpos - N - M -> lookback = N + M NEXT_LAST(v, N, M): 7521a30Row pattern recognition patch (planner).
2615 - * target = currentpos - N + M -> lookback = max(N - M, 0) 7521a30Row pattern recognition patch (planner).
2616 - */ 7521a30Row pattern recognition patch (planner).
2617 1275 if (nav->kind == RPR_NAV_PREV_LAST || 7521a30Row pattern recognition patch (planner).
2618 - nav->kind == RPR_NAV_NEXT_LAST) 7521a30Row pattern recognition patch (planner).
2619 - { 7521a30Row pattern recognition patch (planner).
2620 55 if (!context->maxNeedsEval) 7521a30Row pattern recognition patch (planner).
2621 - { 7521a30Row pattern recognition patch (planner).
2622 55 int64 inner; 7521a30Row pattern recognition patch (planner).
2623 55 int64 outer; 7521a30Row pattern recognition patch (planner).
2624 55 int64 reach; 7521a30Row pattern recognition patch (planner).
2625 - 7521a30Row pattern recognition patch (planner).
2626 105 if (extract_const_offset(nav->offset_arg, 0, &inner) && 7521a30Row pattern recognition patch (planner).
2627 50 extract_const_offset(nav->compound_offset_arg, 1, &outer)) 7521a30Row pattern recognition patch (planner).
2628 - { 7521a30Row pattern recognition patch (planner).
2629 50 if (nav->kind == RPR_NAV_PREV_LAST) 7521a30Row pattern recognition patch (planner).
2630 - { 7521a30Row pattern recognition patch (planner).
2631 20 if (pg_add_s64_overflow(inner, outer, &reach)) 7521a30Row pattern recognition patch (planner).
2632 5 context->maxOverflow = true; 7521a30Row pattern recognition patch (planner).
2633 - else 7521a30Row pattern recognition patch (planner).
2634 15 context->maxOffset = Max(context->maxOffset, reach); 7521a30Row pattern recognition patch (planner).
2635 - } 7521a30Row pattern recognition patch (planner).
2636 - else 7521a30Row pattern recognition patch (planner).
2637 - { 7521a30Row pattern recognition patch (planner).
2638 30 reach = Max(inner - outer, 0); 7521a30Row pattern recognition patch (planner).
2639 30 context->maxOffset = Max(context->maxOffset, reach); 7521a30Row pattern recognition patch (planner).
2640 - } 7521a30Row pattern recognition patch (planner).
2641 - } 7521a30Row pattern recognition patch (planner).
2642 - else 7521a30Row pattern recognition patch (planner).
2643 5 context->maxNeedsEval = true; 7521a30Row pattern recognition patch (planner).
2644 - } 7521a30Row pattern recognition patch (planner).
2645 - } 7521a30Row pattern recognition patch (planner).
2646 - 7521a30Row pattern recognition patch (planner).
2647 - /* 7521a30Row pattern recognition patch (planner).
2648 - * Compound PREV_FIRST / NEXT_FIRST: base = match_start. PREV_FIRST(v, N, 7521a30Row pattern recognition patch (planner).
2649 - * M): target = match_start + N - M NEXT_FIRST(v, N, M): target = 7521a30Row pattern recognition patch (planner).
2650 - * match_start + N + M The combined offset (N+/-M) from match_start can be 7521a30Row pattern recognition patch (planner).
2651 - * negative, meaning rows before match_start are needed. 7521a30Row pattern recognition patch (planner).
2652 - */ 7521a30Row pattern recognition patch (planner).
2653 1275 if (nav->kind == RPR_NAV_PREV_FIRST || 7521a30Row pattern recognition patch (planner).
2654 - nav->kind == RPR_NAV_NEXT_FIRST) 7521a30Row pattern recognition patch (planner).
2655 - { 7521a30Row pattern recognition patch (planner).
2656 110 context->hasFirst = true; 7521a30Row pattern recognition patch (planner).
2657 - 7521a30Row pattern recognition patch (planner).
2658 110 if (!context->firstNeedsEval) 7521a30Row pattern recognition patch (planner).
2659 - { 7521a30Row pattern recognition patch (planner).
2660 110 int64 inner; 7521a30Row pattern recognition patch (planner).
2661 110 int64 outer; 7521a30Row pattern recognition patch (planner).
2662 110 int64 reach; 7521a30Row pattern recognition patch (planner).
2663 - 7521a30Row pattern recognition patch (planner).
2664 215 if (extract_const_offset(nav->offset_arg, 0, &inner) && 7521a30Row pattern recognition patch (planner).
2665 105 extract_const_offset(nav->compound_offset_arg, 1, &outer)) 7521a30Row pattern recognition patch (planner).
2666 - { 7521a30Row pattern recognition patch (planner).
2667 105 if (nav->kind == RPR_NAV_PREV_FIRST) 7521a30Row pattern recognition patch (planner).
2668 - { 7521a30Row pattern recognition patch (planner).
2669 - /* 7521a30Row pattern recognition patch (planner).
2670 - * reach = inner - outer. Both are non-negative, so the 7521a30Row pattern recognition patch (planner).
2671 - * result >= -PG_INT64_MAX, which cannot underflow int64. 7521a30Row pattern recognition patch (planner).
2672 - * No overflow check needed. 7521a30Row pattern recognition patch (planner).
2673 - */ 7521a30Row pattern recognition patch (planner).
2674 80 reach = inner - outer; 7521a30Row pattern recognition patch (planner).
2675 - } 7521a30Row pattern recognition patch (planner).
2676 - else 7521a30Row pattern recognition patch (planner).
2677 - { 7521a30Row pattern recognition patch (planner).
2678 - /* 7521a30Row pattern recognition patch (planner).
2679 - * NEXT_FIRST: reach = inner + outer. This can overflow, 7521a30Row pattern recognition patch (planner).
2680 - * but the result is always >= 0, so it never updates 7521a30Row pattern recognition patch (planner).
2681 - * firstOffset (which tracks the minimum). Clamp to 7521a30Row pattern recognition patch (planner).
2682 - * PG_INT64_MAX on overflow. 7521a30Row pattern recognition patch (planner).
2683 - */ 7521a30Row pattern recognition patch (planner).
2684 25 if (pg_add_s64_overflow(inner, outer, &reach)) 7521a30Row pattern recognition patch (planner).
2685 5 reach = PG_INT64_MAX; 7521a30Row pattern recognition patch (planner).
2686 - } 7521a30Row pattern recognition patch (planner).
2687 - 7521a30Row pattern recognition patch (planner).
2688 105 context->firstOffset = Min(context->firstOffset, reach); 7521a30Row pattern recognition patch (planner).
2689 - } 7521a30Row pattern recognition patch (planner).
2690 - else 7521a30Row pattern recognition patch (planner).
2691 5 context->firstNeedsEval = true; 7521a30Row pattern recognition patch (planner).
2692 - } 7521a30Row pattern recognition patch (planner).
2693 - } 7521a30Row pattern recognition patch (planner).
2694 - 7521a30Row pattern recognition patch (planner).
2695 - /* 7521a30Row pattern recognition patch (planner).
2696 - * Match-start dependency: classify the outer nav kind. A constant 7521a30Row pattern recognition patch (planner).
2697 - * LAST(x, 0) is conservatively included (offset_arg is a non-NULL Const), 7521a30Row pattern recognition patch (planner).
2698 - * causing a harmless extra re-evaluation; since LAST(x, 0) is the current 7521a30Row pattern recognition patch (planner).
2699 - * row, its result is independent of the match start. 7521a30Row pattern recognition patch (planner).
2700 - */ 7521a30Row pattern recognition patch (planner).
2701 1275 if (nav->kind == RPR_NAV_FIRST || 7521a30Row pattern recognition patch (planner).
2702 1215 (nav->kind == RPR_NAV_LAST && nav->offset_arg != NULL) || 7521a30Row pattern recognition patch (planner).
2703 1110 nav->kind == RPR_NAV_PREV_FIRST || 7521a30Row pattern recognition patch (planner).
2704 1080 nav->kind == RPR_NAV_NEXT_FIRST || 7521a30Row pattern recognition patch (planner).
2705 1080 ((nav->kind == RPR_NAV_PREV_LAST || 7521a30Row pattern recognition patch (planner).
2706 55 nav->kind == RPR_NAV_NEXT_LAST) && 7521a30Row pattern recognition patch (planner).
2707 55 nav->offset_arg != NULL)) 7521a30Row pattern recognition patch (planner).
2708 230 context->matchStartDependent = 7521a30Row pattern recognition patch (planner).
2709 230 bms_add_member(context->matchStartDependent, 7521a30Row pattern recognition patch (planner).
2710 - context->curVarIdx); 7521a30Row pattern recognition patch (planner).
2711 1275 } 7521a30Row pattern recognition patch (planner).
compute_define_metadata() lines 2730-2797
Modified Lines Coverage: 35/35 lines (100.0%)
LineHitsSourceCommit
2730 3729 compute_define_metadata(List *defineClause, 7521a30Row pattern recognition patch (planner).
2731 - RPRNavOffsetKind *maxKind, int64 *maxResult, 7521a30Row pattern recognition patch (planner).
2732 - bool *hasFirst, 7521a30Row pattern recognition patch (planner).
2733 - RPRNavOffsetKind *firstKind, int64 *firstResult, 7521a30Row pattern recognition patch (planner).
2734 - Bitmapset **matchStartDependent) 7521a30Row pattern recognition patch (planner).
2735 - { 7521a30Row pattern recognition patch (planner).
2736 3729 DefineMetadataContext ctx; 7521a30Row pattern recognition patch (planner).
2737 3729 NavTraversal trav; 7521a30Row pattern recognition patch (planner).
2738 - 7521a30Row pattern recognition patch (planner).
2739 3729 ctx.maxOffset = 0; 7521a30Row pattern recognition patch (planner).
2740 3729 ctx.maxNeedsEval = false; 7521a30Row pattern recognition patch (planner).
2741 3729 ctx.maxOverflow = false; 7521a30Row pattern recognition patch (planner).
2742 3729 ctx.firstOffset = PG_INT64_MAX; /* sentinel: no FIRST found yet */ 7521a30Row pattern recognition patch (planner).
2743 3729 ctx.hasFirst = false; 7521a30Row pattern recognition patch (planner).
2744 3729 ctx.firstNeedsEval = false; 7521a30Row pattern recognition patch (planner).
2745 3729 ctx.curVarIdx = 0; 7521a30Row pattern recognition patch (planner).
2746 3729 ctx.matchStartDependent = NULL; 7521a30Row pattern recognition patch (planner).
2747 - 7521a30Row pattern recognition patch (planner).
2748 3729 trav.visit = visit_nav_plan; 7521a30Row pattern recognition patch (planner).
2749 3729 trav.data = &ctx; 7521a30Row pattern recognition patch (planner).
2750 - 7521a30Row pattern recognition patch (planner).
2751 12388 foreach_node(TargetEntry, te, defineClause) 7521a30Row pattern recognition patch (planner).
2752 - { 7521a30Row pattern recognition patch (planner).
2753 8659 nav_traversal_walker((Node *) te->expr, &trav); 7521a30Row pattern recognition patch (planner).
2754 8659 ctx.curVarIdx++; 7521a30Row pattern recognition patch (planner).
2755 - } 7521a30Row pattern recognition patch (planner).
2756 - 7521a30Row pattern recognition patch (planner).
2757 3729 *matchStartDependent = ctx.matchStartDependent; 7521a30Row pattern recognition patch (planner).
2758 - 7521a30Row pattern recognition patch (planner).
2759 - /* Max backward offset */ 7521a30Row pattern recognition patch (planner).
2760 3729 if (ctx.maxOverflow) 7521a30Row pattern recognition patch (planner).
2761 - { 7521a30Row pattern recognition patch (planner).
2762 5 *maxKind = RPR_NAV_OFFSET_RETAIN_ALL; 7521a30Row pattern recognition patch (planner).
2763 5 *maxResult = 0; 7521a30Row pattern recognition patch (planner).
2764 - } 7521a30Row pattern recognition patch (planner).
2765 3724 else if (ctx.maxNeedsEval) 7521a30Row pattern recognition patch (planner).
2766 - { 7521a30Row pattern recognition patch (planner).
2767 15 *maxKind = RPR_NAV_OFFSET_NEEDS_EVAL; 7521a30Row pattern recognition patch (planner).
2768 15 *maxResult = 0; 7521a30Row pattern recognition patch (planner).
2769 - } 7521a30Row pattern recognition patch (planner).
2770 - else 7521a30Row pattern recognition patch (planner).
2771 - { 7521a30Row pattern recognition patch (planner).
2772 3709 *maxKind = RPR_NAV_OFFSET_FIXED; 7521a30Row pattern recognition patch (planner).
2773 3709 *maxResult = ctx.maxOffset; 7521a30Row pattern recognition patch (planner).
2774 - } 7521a30Row pattern recognition patch (planner).
2775 - 7521a30Row pattern recognition patch (planner).
2776 - /* First offset (can be negative for compound PREV_FIRST) */ 7521a30Row pattern recognition patch (planner).
2777 3729 *hasFirst = ctx.hasFirst; 7521a30Row pattern recognition patch (planner).
2778 3729 if (ctx.hasFirst) 7521a30Row pattern recognition patch (planner).
2779 - { 7521a30Row pattern recognition patch (planner).
2780 170 if (ctx.firstNeedsEval) 7521a30Row pattern recognition patch (planner).
2781 - { 7521a30Row pattern recognition patch (planner).
2782 5 *firstKind = RPR_NAV_OFFSET_NEEDS_EVAL; 7521a30Row pattern recognition patch (planner).
2783 5 *firstResult = 0; 7521a30Row pattern recognition patch (planner).
2784 - } 7521a30Row pattern recognition patch (planner).
2785 - else 7521a30Row pattern recognition patch (planner).
2786 - { 7521a30Row pattern recognition patch (planner).
2787 165 *firstKind = RPR_NAV_OFFSET_FIXED; 7521a30Row pattern recognition patch (planner).
2788 165 *firstResult = ctx.firstOffset; /* may be negative; PG_INT64_MAX 7521a30Row pattern recognition patch (planner).
2789 - * if overflowed */ 7521a30Row pattern recognition patch (planner).
2790 - } 7521a30Row pattern recognition patch (planner).
2791 - } 7521a30Row pattern recognition patch (planner).
2792 - else 7521a30Row pattern recognition patch (planner).
2793 - { 7521a30Row pattern recognition patch (planner).
2794 3559 *firstKind = RPR_NAV_OFFSET_FIXED; 7521a30Row pattern recognition patch (planner).
2795 3559 *firstResult = 0; 7521a30Row pattern recognition patch (planner).
2796 - } 7521a30Row pattern recognition patch (planner).
2797 3729 } 7521a30Row pattern recognition patch (planner).
create_windowagg_plan() lines 2806-2939
Modified Lines Coverage: 14/14 lines (100.0%)
LineHitsSourceCommit
2806 - create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path) -
2807 - { -
2808 - WindowAgg *plan; -
2809 - WindowClause *wc = best_path->winclause; -
2810 - int numPart = list_length(wc->partitionClause); -
2811 - int numOrder = list_length(wc->orderClause); -
2812 - Plan *subplan; -
2813 - List *tlist; -
2814 - int partNumCols; -
2815 - AttrNumber *partColIdx; -
2816 - Oid *partOperators; -
2817 - Oid *partCollations; -
2818 - int ordNumCols; -
2819 - AttrNumber *ordColIdx; -
2820 - Oid *ordOperators; -
2821 - Oid *ordCollations; -
2822 - ListCell *lc; -
2823 6186 List *defineVariableList = NIL; 7521a30Row pattern recognition patch (planner).
2824 6186 RPRPattern *compiledPattern = NULL; 7521a30Row pattern recognition patch (planner).
2825 6186 Bitmapset *matchStartDependent = NULL; 7521a30Row pattern recognition patch (planner).
2826 6186 RPRNavOffsetKind navMaxOffsetKind = RPR_NAV_OFFSET_FIXED; 7521a30Row pattern recognition patch (planner).
2827 6186 int64 navMaxOffset = 0; 7521a30Row pattern recognition patch (planner).
2828 6186 bool hasFirstNav = false; 7521a30Row pattern recognition patch (planner).
2829 6186 RPRNavOffsetKind navFirstOffsetKind = RPR_NAV_OFFSET_FIXED; 7521a30Row pattern recognition patch (planner).
2830 6186 int64 navFirstOffset = 0; 7521a30Row pattern recognition patch (planner).
2831 - 7521a30Row pattern recognition patch (planner).
2832 - -
2833 - /* -
2834 - * Choice of tlist here is motivated by the fact that WindowAgg will be -
2835 - * storing the input rows of window frames in a tuplestore; it therefore -
2836 - * behooves us to request a small tlist to avoid wasting space. We do of -
2837 - * course need grouping columns to be available. -
2838 - */ -
2839 - subplan = create_plan_recurse(root, best_path->subpath, -
2840 - CP_LABEL_TLIST | CP_SMALL_TLIST); -
2841 - -
2842 - tlist = build_path_tlist(root, &best_path->path); -
2843 - -
2844 - /* -
2845 - * Convert SortGroupClause lists into arrays of attr indexes and equality -
2846 - * operators, as wanted by executor. -
2847 - */ -
2848 - partColIdx = palloc_array(AttrNumber, numPart); -
2849 - partOperators = palloc_array(Oid, numPart); -
2850 - partCollations = palloc_array(Oid, numPart); -
2851 - -
2852 - partNumCols = 0; -
2853 - foreach(lc, wc->partitionClause) -
2854 - { -
2855 - SortGroupClause *sgc = (SortGroupClause *) lfirst(lc); -
2856 - TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist); -
2857 - -
2858 - Assert(OidIsValid(sgc->eqop)); -
2859 - partColIdx[partNumCols] = tle->resno; -
2860 - partOperators[partNumCols] = sgc->eqop; -
2861 - partCollations[partNumCols] = exprCollation((Node *) tle->expr); -
2862 - partNumCols++; -
2863 - } -
2864 - -
2865 - ordColIdx = palloc_array(AttrNumber, numOrder); -
2866 - ordOperators = palloc_array(Oid, numOrder); -
2867 - ordCollations = palloc_array(Oid, numOrder); -
2868 - -
2869 - ordNumCols = 0; -
2870 - foreach(lc, wc->orderClause) -
2871 - { -
2872 - SortGroupClause *sgc = (SortGroupClause *) lfirst(lc); -
2873 - TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist); -
2874 - -
2875 - Assert(OidIsValid(sgc->eqop)); -
2876 - ordColIdx[ordNumCols] = tle->resno; -
2877 - ordOperators[ordNumCols] = sgc->eqop; -
2878 - ordCollations[ordNumCols] = exprCollation((Node *) tle->expr); -
2879 - ordNumCols++; -
2880 - } -
2881 - -
2882 - /* Build RPR pattern and defineVariableList */ 7521a30Row pattern recognition patch (planner).
2883 6186 if (wc->rpPattern) 7521a30Row pattern recognition patch (planner).
2884 - { 7521a30Row pattern recognition patch (planner).
2885 - /* 7521a30Row pattern recognition patch (planner).
2886 - * Build defineVariableList from defineClause. The parser already 7521a30Row pattern recognition patch (planner).
2887 - * rejects DEFINE variables not used in PATTERN, so no filtering is 7521a30Row pattern recognition patch (planner).
2888 - * needed. 7521a30Row pattern recognition patch (planner).
2889 - */ 7521a30Row pattern recognition patch (planner).
2890 12388 foreach_node(TargetEntry, te, wc->defineClause) b848408Tidy up row pattern recognition plumbing
2891 8659 defineVariableList = lappend(defineVariableList, b848408Tidy up row pattern recognition plumbing
2892 8659 makeString(pstrdup(te->resname))); b848408Tidy up row pattern recognition plumbing
2893 - 7521a30Row pattern recognition patch (planner).
2894 - /* 7521a30Row pattern recognition patch (planner).
2895 - * Walk DEFINE once: collect nav offsets (for tuplestore trim) and the 7521a30Row pattern recognition patch (planner).
2896 - * bitmapset of match_start-dependent variables (for absorption 7521a30Row pattern recognition patch (planner).
2897 - * suppression in buildRPRPattern). 7521a30Row pattern recognition patch (planner).
2898 - */ 7521a30Row pattern recognition patch (planner).
2899 3729 compute_define_metadata(wc->defineClause, 7521a30Row pattern recognition patch (planner).
2900 - &navMaxOffsetKind, &navMaxOffset, 7521a30Row pattern recognition patch (planner).
2901 - &hasFirstNav, 7521a30Row pattern recognition patch (planner).
2902 - &navFirstOffsetKind, &navFirstOffset, 7521a30Row pattern recognition patch (planner).
2903 - &matchStartDependent); 7521a30Row pattern recognition patch (planner).
2904 - 7521a30Row pattern recognition patch (planner).
2905 - /* Compile and optimize RPR patterns */ 7521a30Row pattern recognition patch (planner).
2906 3729 compiledPattern = buildRPRPattern(wc->rpPattern, 7521a30Row pattern recognition patch (planner).
2907 - defineVariableList, 7521a30Row pattern recognition patch (planner).
2908 - wc->rpSkipTo, 7521a30Row pattern recognition patch (planner).
2909 - wc->frameOptions, 7521a30Row pattern recognition patch (planner).
2910 - !bms_is_empty(matchStartDependent)); 7521a30Row pattern recognition patch (planner).
2911 - } 7521a30Row pattern recognition patch (planner).
2912 - 7521a30Row pattern recognition patch (planner).
2913 - /* And finally we can make the WindowAgg node */ -
2914 - plan = make_windowagg(tlist, -
2915 - wc, -
2916 - partNumCols, -
2917 - partColIdx, -
2918 - partOperators, -
2919 - partCollations, -
2920 - ordNumCols, -
2921 - ordColIdx, -
2922 - ordOperators, -
2923 - ordCollations, -
2924 - best_path->runCondition, -
2925 - compiledPattern, 7521a30Row pattern recognition patch (planner).
2926 - matchStartDependent, 7521a30Row pattern recognition patch (planner).
2927 - navMaxOffsetKind, b848408Tidy up row pattern recognition plumbing
2928 - navMaxOffset, b848408Tidy up row pattern recognition plumbing
2929 - hasFirstNav, 7521a30Row pattern recognition patch (planner).
2930 - navFirstOffsetKind, b848408Tidy up row pattern recognition plumbing
2931 - navFirstOffset, b848408Tidy up row pattern recognition plumbing
2932 - best_path->qual, -
2933 - best_path->topwindow, -
2934 - subplan); -
2935 - -
2936 - copy_generic_path_info(&plan->plan, (Path *) best_path); -
2937 - -
2938 - return plan; -
2939 - } -