@@ -128,11 +128,13 @@ static RelOptInfo *create_distinct_paths(PlannerInfo *root,
128128static RelOptInfo * create_ordered_paths (PlannerInfo * root ,
129129 RelOptInfo * input_rel ,
130130 double limit_tuples );
131- static PathTarget * make_group_input_target (PlannerInfo * root , List * tlist );
131+ static PathTarget * make_group_input_target (PlannerInfo * root ,
132+ PathTarget * final_target );
132133static List * postprocess_setop_tlist (List * new_tlist , List * orig_tlist );
133134static List * select_active_windows (PlannerInfo * root , WindowFuncLists * wflists );
134135static PathTarget * make_window_input_target (PlannerInfo * root ,
135- List * tlist , List * activeWindows );
136+ PathTarget * final_target ,
137+ List * activeWindows );
136138static List * make_pathkeys_for_window (PlannerInfo * root , WindowClause * wc ,
137139 List * tlist );
138140
@@ -1664,7 +1666,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16641666 */
16651667 if (activeWindows )
16661668 grouping_target = make_window_input_target (root ,
1667- tlist ,
1669+ final_target ,
16681670 activeWindows );
16691671 else
16701672 grouping_target = final_target ;
@@ -1678,7 +1680,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
16781680 have_grouping = (parse -> groupClause || parse -> groupingSets ||
16791681 parse -> hasAggs || root -> hasHavingQual );
16801682 if (have_grouping )
1681- scanjoin_target = make_group_input_target (root , tlist );
1683+ scanjoin_target = make_group_input_target (root , final_target );
16821684 else
16831685 scanjoin_target = grouping_target ;
16841686
@@ -3758,10 +3760,10 @@ create_ordered_paths(PlannerInfo *root,
37583760 *
37593761 * If there is grouping or aggregation, the scan/join subplan cannot emit
37603762 * the query's final targetlist; for example, it certainly can't emit any
3761- * aggregate function calls. This routine generates the correct target list
3763+ * aggregate function calls. This routine generates the correct target
37623764 * for the scan/join subplan.
37633765 *
3764- * The initial target list passed from the parser already contains entries
3766+ * The query target list passed from the parser already contains entries
37653767 * for all ORDER BY and GROUP BY expressions, but it will not have entries
37663768 * for variables used only in HAVING clauses; so we need to add those
37673769 * variables to the subplan target list. Also, we flatten all expressions
@@ -3774,56 +3776,52 @@ create_ordered_paths(PlannerInfo *root,
37743776 * where the a+b target will be used by the Sort/Group steps, and the
37753777 * other targets will be used for computing the final results.
37763778 *
3777- * 'tlist ' is the query's final target list.
3779+ * 'final_target ' is the query's final target list (in PathTarget form)
37783780 *
37793781 * The result is the PathTarget to be computed by the Paths returned from
37803782 * query_planner().
37813783 */
37823784static PathTarget *
3783- make_group_input_target (PlannerInfo * root , List * tlist )
3785+ make_group_input_target (PlannerInfo * root , PathTarget * final_target )
37843786{
37853787 Query * parse = root -> parse ;
3786- List * sub_tlist ;
3788+ PathTarget * input_target ;
37873789 List * non_group_cols ;
37883790 List * non_group_vars ;
3789- ListCell * tl ;
3791+ int i ;
3792+ ListCell * lc ;
37903793
37913794 /*
3792- * We must build a tlist containing all grouping columns, plus any other
3793- * Vars mentioned in the targetlist and HAVING qual.
3795+ * We must build a target containing all grouping columns, plus any other
3796+ * Vars mentioned in the query's targetlist and HAVING qual.
37943797 */
3795- sub_tlist = NIL ;
3798+ input_target = create_empty_pathtarget () ;
37963799 non_group_cols = NIL ;
37973800
3798- foreach (tl , tlist )
3801+ i = 0 ;
3802+ foreach (lc , final_target -> exprs )
37993803 {
3800- TargetEntry * tle = (TargetEntry * ) lfirst (tl );
3804+ Expr * expr = (Expr * ) lfirst (lc );
3805+ Index sgref = final_target -> sortgrouprefs [i ];
38013806
3802- if (tle -> ressortgroupref && parse -> groupClause &&
3803- get_sortgroupref_clause_noerr (tle -> ressortgroupref ,
3804- parse -> groupClause ) != NULL )
3807+ if (sgref && parse -> groupClause &&
3808+ get_sortgroupref_clause_noerr (sgref , parse -> groupClause ) != NULL )
38053809 {
38063810 /*
3807- * It's a grouping column, so add it to the result tlist as-is.
3811+ * It's a grouping column, so add it to the input target as-is.
38083812 */
3809- TargetEntry * newtle ;
3810-
3811- newtle = makeTargetEntry (tle -> expr ,
3812- list_length (sub_tlist ) + 1 ,
3813- NULL ,
3814- false);
3815- newtle -> ressortgroupref = tle -> ressortgroupref ;
3816- sub_tlist = lappend (sub_tlist , newtle );
3813+ add_column_to_pathtarget (input_target , expr , sgref );
38173814 }
38183815 else
38193816 {
38203817 /*
38213818 * Non-grouping column, so just remember the expression for later
3822- * call to pull_var_clause. There's no need for pull_var_clause
3823- * to examine the TargetEntry node itself.
3819+ * call to pull_var_clause.
38243820 */
3825- non_group_cols = lappend (non_group_cols , tle -> expr );
3821+ non_group_cols = lappend (non_group_cols , expr );
38263822 }
3823+
3824+ i ++ ;
38273825 }
38283826
38293827 /*
@@ -3834,7 +3832,7 @@ make_group_input_target(PlannerInfo *root, List *tlist)
38343832
38353833 /*
38363834 * Pull out all the Vars mentioned in non-group cols (plus HAVING), and
3837- * add them to the result tlist if not already present. (A Var used
3835+ * add them to the input target if not already present. (A Var used
38383836 * directly as a GROUP BY item will be present already.) Note this
38393837 * includes Vars used in resjunk items, so we are covering the needs of
38403838 * ORDER BY and window specifications. Vars used within Aggrefs and
@@ -3844,13 +3842,14 @@ make_group_input_target(PlannerInfo *root, List *tlist)
38443842 PVC_RECURSE_AGGREGATES |
38453843 PVC_RECURSE_WINDOWFUNCS |
38463844 PVC_INCLUDE_PLACEHOLDERS );
3847- sub_tlist = add_to_flat_tlist ( sub_tlist , non_group_vars );
3845+ add_new_columns_to_pathtarget ( input_target , non_group_vars );
38483846
38493847 /* clean up cruft */
38503848 list_free (non_group_vars );
38513849 list_free (non_group_cols );
38523850
3853- return create_pathtarget (root , sub_tlist );
3851+ /* XXX this causes some redundant cost calculation ... */
3852+ return set_pathtarget_cost_width (root , input_target );
38543853}
38553854
38563855/*
@@ -3964,13 +3963,13 @@ select_active_windows(PlannerInfo *root, WindowFuncLists *wflists)
39643963 * make_window_input_target
39653964 * Generate appropriate PathTarget for initial input to WindowAgg nodes.
39663965 *
3967- * When the query has window functions, this function computes the initial
3968- * target list to be computed by the node just below the first WindowAgg.
3966+ * When the query has window functions, this function computes the desired
3967+ * target to be computed by the node just below the first WindowAgg.
39693968 * This tlist must contain all values needed to evaluate the window functions,
39703969 * compute the final target list, and perform any required final sort step.
39713970 * If multiple WindowAggs are needed, each intermediate one adds its window
3972- * function results onto this tlist; only the topmost WindowAgg computes the
3973- * actual desired target list.
3971+ * function results onto this base tlist; only the topmost WindowAgg computes
3972+ * the actual desired target list.
39743973 *
39753974 * This function is much like make_group_input_target, though not quite enough
39763975 * like it to share code. As in that function, we flatten most expressions
@@ -3986,7 +3985,7 @@ select_active_windows(PlannerInfo *root, WindowFuncLists *wflists)
39863985 * flatten Aggref expressions, since those are to be computed below the
39873986 * window functions and just referenced like Vars above that.
39883987 *
3989- * 'tlist ' is the query's final target list.
3988+ * 'final_target ' is the query's final target list (in PathTarget form)
39903989 * 'activeWindows' is the list of active windows previously identified by
39913990 * select_active_windows.
39923991 *
@@ -3995,14 +3994,15 @@ select_active_windows(PlannerInfo *root, WindowFuncLists *wflists)
39953994 */
39963995static PathTarget *
39973996make_window_input_target (PlannerInfo * root ,
3998- List * tlist ,
3997+ PathTarget * final_target ,
39993998 List * activeWindows )
40003999{
40014000 Query * parse = root -> parse ;
4001+ PathTarget * input_target ;
40024002 Bitmapset * sgrefs ;
4003- List * new_tlist ;
40044003 List * flattenable_cols ;
40054004 List * flattenable_vars ;
4005+ int i ;
40064006 ListCell * lc ;
40074007
40084008 Assert (parse -> hasWindowFuncs );
@@ -4040,52 +4040,49 @@ make_window_input_target(PlannerInfo *root,
40404040 }
40414041
40424042 /*
4043- * Construct a tlist containing all the non-flattenable tlist items, and
4044- * save aside the others for a moment.
4043+ * Construct a target containing all the non-flattenable targetlist items,
4044+ * and save aside the others for a moment.
40454045 */
4046- new_tlist = NIL ;
4046+ input_target = create_empty_pathtarget () ;
40474047 flattenable_cols = NIL ;
40484048
4049- foreach (lc , tlist )
4049+ i = 0 ;
4050+ foreach (lc , final_target -> exprs )
40504051 {
4051- TargetEntry * tle = (TargetEntry * ) lfirst (lc );
4052+ Expr * expr = (Expr * ) lfirst (lc );
4053+ Index sgref = final_target -> sortgrouprefs [i ];
40524054
40534055 /*
40544056 * Don't want to deconstruct window clauses or GROUP BY items. (Note
40554057 * that such items can't contain window functions, so it's okay to
40564058 * compute them below the WindowAgg nodes.)
40574059 */
4058- if (tle -> ressortgroupref != 0 &&
4059- bms_is_member (tle -> ressortgroupref , sgrefs ))
4060+ if (sgref != 0 && bms_is_member (sgref , sgrefs ))
40604061 {
4061- /* Don't want to deconstruct this value, so add to new_tlist */
4062- TargetEntry * newtle ;
4063-
4064- newtle = makeTargetEntry (tle -> expr ,
4065- list_length (new_tlist ) + 1 ,
4066- NULL ,
4067- false);
4068- /* Preserve its sortgroupref marking, in case it's volatile */
4069- newtle -> ressortgroupref = tle -> ressortgroupref ;
4070- new_tlist = lappend (new_tlist , newtle );
4062+ /*
4063+ * Don't want to deconstruct this value, so add it to the input
4064+ * target as-is.
4065+ */
4066+ add_column_to_pathtarget (input_target , expr , sgref );
40714067 }
40724068 else
40734069 {
40744070 /*
40754071 * Column is to be flattened, so just remember the expression for
4076- * later call to pull_var_clause. There's no need for
4077- * pull_var_clause to examine the TargetEntry node itself.
4072+ * later call to pull_var_clause.
40784073 */
4079- flattenable_cols = lappend (flattenable_cols , tle -> expr );
4074+ flattenable_cols = lappend (flattenable_cols , expr );
40804075 }
4076+
4077+ i ++ ;
40814078 }
40824079
40834080 /*
40844081 * Pull out all the Vars and Aggrefs mentioned in flattenable columns, and
4085- * add them to the result tlist if not already present. (Some might be
4082+ * add them to the input target if not already present. (Some might be
40864083 * there already because they're used directly as window/group clauses.)
40874084 *
4088- * Note: it's essential to use PVC_INCLUDE_AGGREGATES here, so that the
4085+ * Note: it's essential to use PVC_INCLUDE_AGGREGATES here, so that any
40894086 * Aggrefs are placed in the Agg node's tlist and not left to be computed
40904087 * at higher levels. On the other hand, we should recurse into
40914088 * WindowFuncs to make sure their input expressions are available.
@@ -4094,13 +4091,14 @@ make_window_input_target(PlannerInfo *root,
40944091 PVC_INCLUDE_AGGREGATES |
40954092 PVC_RECURSE_WINDOWFUNCS |
40964093 PVC_INCLUDE_PLACEHOLDERS );
4097- new_tlist = add_to_flat_tlist ( new_tlist , flattenable_vars );
4094+ add_new_columns_to_pathtarget ( input_target , flattenable_vars );
40984095
40994096 /* clean up cruft */
41004097 list_free (flattenable_vars );
41014098 list_free (flattenable_cols );
41024099
4103- return create_pathtarget (root , new_tlist );
4100+ /* XXX this causes some redundant cost calculation ... */
4101+ return set_pathtarget_cost_width (root , input_target );
41044102}
41054103
41064104/*
0 commit comments