54
54
#include "optimizer/tlist.h"
55
55
#include "parser/analyze.h"
56
56
#include "parser/parse_agg.h"
57
- #include "parser/parse_clause.h"
58
57
#include "parser/parse_relation.h"
59
58
#include "parser/parsetree.h"
60
59
#include "partitioning/partdesc.h"
@@ -120,15 +119,12 @@ typedef struct
120
119
{
121
120
List * activeWindows ; /* active windows, if any */
122
121
grouping_sets_data * gset_data ; /* grouping sets data, if any */
123
- SetOperationStmt * setop ; /* parent set operation or NULL if not a
124
- * subquery belonging to a set operation */
125
122
} standard_qp_extra ;
126
123
127
124
/* Local functions */
128
125
static Node * preprocess_expression (PlannerInfo * root , Node * expr , int kind );
129
126
static void preprocess_qual_conditions (PlannerInfo * root , Node * jtnode );
130
- static void grouping_planner (PlannerInfo * root , double tuple_fraction ,
131
- SetOperationStmt * setops );
127
+ static void grouping_planner (PlannerInfo * root , double tuple_fraction );
132
128
static grouping_sets_data * preprocess_grouping_sets (PlannerInfo * root );
133
129
static List * remap_to_groupclause_idx (List * groupClause , List * gsets ,
134
130
int * tleref_to_colnum_map );
@@ -253,8 +249,6 @@ static bool group_by_has_partkey(RelOptInfo *input_rel,
253
249
List * targetList ,
254
250
List * groupClause );
255
251
static int common_prefix_cmp (const void * a , const void * b );
256
- static List * generate_setop_child_grouplist (SetOperationStmt * op ,
257
- List * targetlist );
258
252
259
253
260
254
/*****************************************************************************
@@ -412,7 +406,8 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
412
406
}
413
407
414
408
/* primary planning entry point (may recurse for subqueries) */
415
- root = subquery_planner (glob , parse , NULL , false, tuple_fraction , NULL );
409
+ root = subquery_planner (glob , parse , NULL ,
410
+ false, tuple_fraction );
416
411
417
412
/* Select best Path and turn it into a Plan */
418
413
final_rel = fetch_upper_rel (root , UPPERREL_FINAL , NULL );
@@ -603,10 +598,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
603
598
* hasRecursion is true if this is a recursive WITH query.
604
599
* tuple_fraction is the fraction of tuples we expect will be retrieved.
605
600
* tuple_fraction is interpreted as explained for grouping_planner, below.
606
- * setops is used for set operation subqueries to provide the subquery with
607
- * the context in which it's being used so that Paths correctly sorted for the
608
- * set operation can be generated. NULL when not planning a set operation
609
- * child.
610
601
*
611
602
* Basically, this routine does the stuff that should only be done once
612
603
* per Query object. It then calls grouping_planner. At one time,
@@ -625,9 +616,9 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
625
616
*--------------------
626
617
*/
627
618
PlannerInfo *
628
- subquery_planner (PlannerGlobal * glob , Query * parse , PlannerInfo * parent_root ,
629
- bool hasRecursion , double tuple_fraction ,
630
- SetOperationStmt * setops )
619
+ subquery_planner (PlannerGlobal * glob , Query * parse ,
620
+ PlannerInfo * parent_root ,
621
+ bool hasRecursion , double tuple_fraction )
631
622
{
632
623
PlannerInfo * root ;
633
624
List * newWithCheckOptions ;
@@ -1086,7 +1077,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root,
1086
1077
/*
1087
1078
* Do the main planning.
1088
1079
*/
1089
- grouping_planner (root , tuple_fraction , setops );
1080
+ grouping_planner (root , tuple_fraction );
1090
1081
1091
1082
/*
1092
1083
* Capture the set of outer-level param IDs we have access to, for use in
@@ -1284,11 +1275,7 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr)
1284
1275
* 0 < tuple_fraction < 1: expect the given fraction of tuples available
1285
1276
* from the plan to be retrieved
1286
1277
* tuple_fraction >= 1: tuple_fraction is the absolute number of tuples
1287
- * expected to be retrieved (ie, a LIMIT specification).
1288
- * setops is used for set operation subqueries to provide the subquery with
1289
- * the context in which it's being used so that Paths correctly sorted for the
1290
- * set operation can be generated. NULL when not planning a set operation
1291
- * child.
1278
+ * expected to be retrieved (ie, a LIMIT specification)
1292
1279
*
1293
1280
* Returns nothing; the useful output is in the Paths we attach to the
1294
1281
* (UPPERREL_FINAL, NULL) upperrel in *root. In addition,
@@ -1299,8 +1286,7 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr)
1299
1286
*--------------------
1300
1287
*/
1301
1288
static void
1302
- grouping_planner (PlannerInfo * root , double tuple_fraction ,
1303
- SetOperationStmt * setops )
1289
+ grouping_planner (PlannerInfo * root , double tuple_fraction )
1304
1290
{
1305
1291
Query * parse = root -> parse ;
1306
1292
int64 offset_est = 0 ;
@@ -1335,6 +1321,17 @@ grouping_planner(PlannerInfo *root, double tuple_fraction,
1335
1321
1336
1322
if (parse -> setOperations )
1337
1323
{
1324
+ /*
1325
+ * If there's a top-level ORDER BY, assume we have to fetch all the
1326
+ * tuples. This might be too simplistic given all the hackery below
1327
+ * to possibly avoid the sort; but the odds of accurate estimates here
1328
+ * are pretty low anyway. XXX try to get rid of this in favor of
1329
+ * letting plan_set_operations generate both fast-start and
1330
+ * cheapest-total paths.
1331
+ */
1332
+ if (parse -> sortClause )
1333
+ root -> tuple_fraction = 0.0 ;
1334
+
1338
1335
/*
1339
1336
* Construct Paths for set operations. The results will not need any
1340
1337
* work except perhaps a top-level sort and/or LIMIT. Note that any
@@ -1504,12 +1501,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction,
1504
1501
qp_extra .activeWindows = activeWindows ;
1505
1502
qp_extra .gset_data = gset_data ;
1506
1503
1507
- /*
1508
- * If we're a subquery for a set operation, store the SetOperationStmt
1509
- * in qp_extra.
1510
- */
1511
- qp_extra .setop = setops ;
1512
-
1513
1504
/*
1514
1505
* Generate the best unsorted and presorted paths for the scan/join
1515
1506
* portion of this Query, ie the processing represented by the
@@ -3462,27 +3453,6 @@ standard_qp_callback(PlannerInfo *root, void *extra)
3462
3453
parse -> sortClause ,
3463
3454
tlist );
3464
3455
3465
- /* setting setop_pathkeys might be useful to the union planner */
3466
- if (qp_extra -> setop != NULL &&
3467
- set_operation_ordered_results_useful (qp_extra -> setop ))
3468
- {
3469
- List * groupClauses ;
3470
- bool sortable ;
3471
-
3472
- groupClauses = generate_setop_child_grouplist (qp_extra -> setop , tlist );
3473
-
3474
- root -> setop_pathkeys =
3475
- make_pathkeys_for_sortclauses_extended (root ,
3476
- & groupClauses ,
3477
- tlist ,
3478
- false,
3479
- & sortable );
3480
- if (!sortable )
3481
- root -> setop_pathkeys = NIL ;
3482
- }
3483
- else
3484
- root -> setop_pathkeys = NIL ;
3485
-
3486
3456
/*
3487
3457
* Figure out whether we want a sorted result from query_planner.
3488
3458
*
@@ -3492,9 +3462,7 @@ standard_qp_callback(PlannerInfo *root, void *extra)
3492
3462
* sortable DISTINCT clause that's more rigorous than the ORDER BY clause,
3493
3463
* we try to produce output that's sufficiently well sorted for the
3494
3464
* DISTINCT. Otherwise, if there is an ORDER BY clause, we want to sort
3495
- * by the ORDER BY clause. Otherwise, if we're a subquery being planned
3496
- * for a set operation which can benefit from presorted results and have a
3497
- * sortable targetlist, we want to sort by the target list.
3465
+ * by the ORDER BY clause.
3498
3466
*
3499
3467
* Note: if we have both ORDER BY and GROUP BY, and ORDER BY is a superset
3500
3468
* of GROUP BY, it would be tempting to request sort by ORDER BY --- but
@@ -3512,8 +3480,6 @@ standard_qp_callback(PlannerInfo *root, void *extra)
3512
3480
root -> query_pathkeys = root -> distinct_pathkeys ;
3513
3481
else if (root -> sort_pathkeys )
3514
3482
root -> query_pathkeys = root -> sort_pathkeys ;
3515
- else if (root -> setop_pathkeys != NIL )
3516
- root -> query_pathkeys = root -> setop_pathkeys ;
3517
3483
else
3518
3484
root -> query_pathkeys = NIL ;
3519
3485
}
@@ -7957,43 +7923,3 @@ group_by_has_partkey(RelOptInfo *input_rel,
7957
7923
7958
7924
return true;
7959
7925
}
7960
-
7961
- /*
7962
- * generate_setop_child_grouplist
7963
- * Build a SortGroupClause list defining the sort/grouping properties
7964
- * of the child of a set operation.
7965
- *
7966
- * This is similar to generate_setop_grouplist() but differs as the setop
7967
- * child query's targetlist entries may already have a tleSortGroupRef
7968
- * assigned for other purposes, such as GROUP BYs. Here we keep the
7969
- * SortGroupClause list in the same order as 'op' groupClauses and just adjust
7970
- * the tleSortGroupRef to reference the TargetEntry's 'ressortgroupref'.
7971
- */
7972
- static List *
7973
- generate_setop_child_grouplist (SetOperationStmt * op , List * targetlist )
7974
- {
7975
- List * grouplist = copyObject (op -> groupClauses );
7976
- ListCell * lg ;
7977
- ListCell * lt ;
7978
-
7979
- lg = list_head (grouplist );
7980
- foreach (lt , targetlist )
7981
- {
7982
- TargetEntry * tle = (TargetEntry * ) lfirst (lt );
7983
- SortGroupClause * sgc ;
7984
-
7985
- /* resjunk columns could have sortgrouprefs. Leave these alone */
7986
- if (tle -> resjunk )
7987
- continue ;
7988
-
7989
- /* we expect every non-resjunk target to have a SortGroupClause */
7990
- Assert (lg != NULL );
7991
- sgc = (SortGroupClause * ) lfirst (lg );
7992
- lg = lnext (grouplist , lg );
7993
-
7994
- /* assign a tleSortGroupRef, or reuse the existing one */
7995
- sgc -> tleSortGroupRef = assignSortGroupRef (tle , targetlist );
7996
- }
7997
- Assert (lg == NULL );
7998
- return grouplist ;
7999
- }
0 commit comments