|
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); |
|