|
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 | returnnode;
|
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 | +intoffset_est,intcount_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 |
| -int32offset=DatumGetInt32(limito->constvalue); |
| 2703 | +doubleoffset_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 |
| -int32count=DatumGetInt32(limitc->constvalue); |
| 2722 | +doublecount_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);
|
|