| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
ReachableHow 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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). |
| Line | Hits | Source | Commit |
|---|---|---|---|
| 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 | - | } | - |