|
10 | 10 | *
|
11 | 11 | *
|
12 | 12 | * IDENTIFICATION
|
13 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.196 2005/07/28 20:26:21 tgl Exp $ |
| 13 | + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.197 2005/08/18 17:51:11 tgl Exp $ |
14 | 14 | *
|
15 | 15 | *-------------------------------------------------------------------------
|
16 | 16 | */
|
@@ -2673,55 +2673,67 @@ make_setop(SetOpCmd cmd, Plan *lefttree,
|
2673 | 2673 | return node;
|
2674 | 2674 | }
|
2675 | 2675 |
|
| 2676 | +/* |
| 2677 | + * Note: offset_est and count_est are passed in to save having to repeat |
| 2678 | + * work already done to estimate the values of the limitOffset and limitCount |
| 2679 | + * expressions. Their values are as returned by preprocess_limit (0 means |
| 2680 | + * "not relevant", -1 means "couldn't estimate"). Keep the code below in sync |
| 2681 | + * with that function! |
| 2682 | + */ |
2676 | 2683 | Limit *
|
2677 |
| -make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount) |
| 2684 | +make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount, |
| 2685 | + int offset_est, int count_est) |
2678 | 2686 | {
|
2679 | 2687 | Limit *node = makeNode(Limit);
|
2680 | 2688 | Plan *plan = &node->plan;
|
2681 | 2689 |
|
2682 | 2690 | copy_plan_costsize(plan, lefttree);
|
2683 | 2691 |
|
2684 | 2692 | /*
|
2685 |
| - * If offset/count are constants, adjust the output rows count and |
2686 |
| - * costs accordingly. This is only a cosmetic issue if we are at top |
2687 |
| - * level, but if we are building a subquery then it's important to |
2688 |
| - * report correct info to the outer planner. |
| 2693 | + * Adjust the output rows count and costs according to the offset/limit. |
| 2694 | + * This is only a cosmetic issue if we are at top level, but if we are |
| 2695 | + * building a subquery then it's important to report correct info to the |
| 2696 | + * outer planner. |
| 2697 | + * |
| 2698 | + * When the offset or count couldn't be estimated, use 10% of the |
| 2699 | + * estimated number of rows emitted from the subplan. |
2689 | 2700 | */
|
2690 |
| - if (limitOffset && IsA(limitOffset, Const)) |
| 2701 | + if (offset_est != 0) |
2691 | 2702 | {
|
2692 |
| - Const *limito = (Const *) limitOffset; |
2693 |
| - int32 offset = DatumGetInt32(limito->constvalue); |
| 2703 | + double offset_rows; |
2694 | 2704 |
|
2695 |
| - if (!limito->constisnull && offset > 0) |
2696 |
| - { |
2697 |
| - if (offset > plan->plan_rows) |
2698 |
| - offset = (int32) plan->plan_rows; |
2699 |
| - if (plan->plan_rows > 0) |
2700 |
| - plan->startup_cost += |
2701 |
| - (plan->total_cost - plan->startup_cost) |
2702 |
| - * ((double) offset) / plan->plan_rows; |
2703 |
| - plan->plan_rows -= offset; |
2704 |
| - if (plan->plan_rows < 1) |
2705 |
| - plan->plan_rows = 1; |
2706 |
| - } |
| 2705 | + if (offset_est > 0) |
| 2706 | + offset_rows = (double) offset_est; |
| 2707 | + else |
| 2708 | + offset_rows = clamp_row_est(lefttree->plan_rows * 0.10); |
| 2709 | + if (offset_rows > plan->plan_rows) |
| 2710 | + offset_rows = plan->plan_rows; |
| 2711 | + if (plan->plan_rows > 0) |
| 2712 | + plan->startup_cost += |
| 2713 | + (plan->total_cost - plan->startup_cost) |
| 2714 | + * offset_rows / plan->plan_rows; |
| 2715 | + plan->plan_rows -= offset_rows; |
| 2716 | + if (plan->plan_rows < 1) |
| 2717 | + plan->plan_rows = 1; |
2707 | 2718 | }
|
2708 |
| - if (limitCount && IsA(limitCount, Const)) |
| 2719 | + |
| 2720 | + if (count_est != 0) |
2709 | 2721 | {
|
2710 |
| - Const *limitc = (Const *) limitCount; |
2711 |
| - int32 count = DatumGetInt32(limitc->constvalue); |
| 2722 | + double count_rows; |
2712 | 2723 |
|
2713 |
| - if (!limitc->constisnull && count >= 0) |
2714 |
| - { |
2715 |
| - if (count > plan->plan_rows) |
2716 |
| - count = (int32) plan->plan_rows; |
2717 |
| - if (plan->plan_rows > 0) |
2718 |
| - plan->total_cost = plan->startup_cost + |
2719 |
| - (plan->total_cost - plan->startup_cost) |
2720 |
| - * ((double) count) / plan->plan_rows; |
2721 |
| - plan->plan_rows = count; |
2722 |
| - if (plan->plan_rows < 1) |
2723 |
| - plan->plan_rows = 1; |
2724 |
| - } |
| 2724 | + if (count_est > 0) |
| 2725 | + count_rows = (double) count_est; |
| 2726 | + else |
| 2727 | + count_rows = clamp_row_est(lefttree->plan_rows * 0.10); |
| 2728 | + if (count_rows > plan->plan_rows) |
| 2729 | + count_rows = plan->plan_rows; |
| 2730 | + if (plan->plan_rows > 0) |
| 2731 | + plan->total_cost = plan->startup_cost + |
| 2732 | + (plan->total_cost - plan->startup_cost) |
| 2733 | + * count_rows / plan->plan_rows; |
| 2734 | + plan->plan_rows = count_rows; |
| 2735 | + if (plan->plan_rows < 1) |
| 2736 | + plan->plan_rows = 1; |
2725 | 2737 | }
|
2726 | 2738 |
|
2727 | 2739 | plan->targetlist = copyObject(lefttree->targetlist);
|
|
0 commit comments