@ -127,7 +127,8 @@ typedef struct
/* Local functions */
static Node * preprocess_expression ( PlannerInfo * root , Node * expr , int kind ) ;
static void preprocess_qual_conditions ( PlannerInfo * root , Node * jtnode ) ;
static void grouping_planner ( PlannerInfo * root , double tuple_fraction ) ;
static void grouping_planner ( PlannerInfo * root , double tuple_fraction ,
SetOperationStmt * setops ) ;
static grouping_sets_data * preprocess_grouping_sets ( PlannerInfo * root ) ;
static List * remap_to_groupclause_idx ( List * groupClause , List * gsets ,
int * tleref_to_colnum_map ) ;
@ -411,8 +412,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
}
/* primary planning entry point (may recurse for subqueries) */
root = subquery_planner ( glob , parse , NULL ,
false , tuple_fraction ) ;
root = subquery_planner ( glob , parse , NULL , false , tuple_fraction , NULL ) ;
/* Select best Path and turn it into a Plan */
final_rel = fetch_upper_rel ( root , UPPERREL_FINAL , NULL ) ;
@ -603,6 +603,10 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
* hasRecursion is true if this is a recursive WITH query .
* tuple_fraction is the fraction of tuples we expect will be retrieved .
* tuple_fraction is interpreted as explained for grouping_planner , below .
* setops is used for set operation subqueries to provide the subquery with
* the context in which it ' s being used so that Paths correctly sorted for the
* set operation can be generated . NULL when not planning a set operation
* child .
*
* Basically , this routine does the stuff that should only be done once
* per Query object . It then calls grouping_planner . At one time ,
@ -621,9 +625,9 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
* - - - - - - - - - - - - - - - - - - - -
*/
PlannerInfo *
subquery_planner ( PlannerGlobal * glob , Query * parse ,
PlannerInfo * parent_root ,
bool hasRecursion , double tuple_fraction )
subquery_planner ( PlannerGlobal * glob , Query * parse , PlannerInfo * parent_root ,
bool hasRecursion , double tuple_fraction ,
SetOperationStmt * setops )
{
PlannerInfo * root ;
List * newWithCheckOptions ;
@ -1085,7 +1089,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
/*
* Do the main planning .
*/
grouping_planner ( root , tuple_fraction ) ;
grouping_planner ( root , tuple_fraction , setops ) ;
/*
* Capture the set of outer - level param IDs we have access to , for use in
@ -1283,7 +1287,11 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr)
* 0 < tuple_fraction < 1 : expect the given fraction of tuples available
* from the plan to be retrieved
* tuple_fraction > = 1 : tuple_fraction is the absolute number of tuples
* expected to be retrieved ( ie , a LIMIT specification )
* expected to be retrieved ( ie , a LIMIT specification ) .
* setops is used for set operation subqueries to provide the subquery with
* the context in which it ' s being used so that Paths correctly sorted for the
* set operation can be generated . NULL when not planning a set operation
* child .
*
* Returns nothing ; the useful output is in the Paths we attach to the
* ( UPPERREL_FINAL , NULL ) upperrel in * root . In addition ,
@ -1294,7 +1302,8 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr)
* - - - - - - - - - - - - - - - - - - - -
*/
static void
grouping_planner ( PlannerInfo * root , double tuple_fraction )
grouping_planner ( PlannerInfo * root , double tuple_fraction ,
SetOperationStmt * setops )
{
Query * parse = root - > parse ;
int64 offset_est = 0 ;
@ -1510,16 +1519,10 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
qp_extra . gset_data = gset_data ;
/*
* Check i f we ' re a subquery for a set operation . If we are , store
* the SetOperationStmt in qp_extra .
* I f we ' re a subquery for a set operation , store the SetOperationStmt
* in qp_extra .
*/
if ( root - > parent_root ! = NULL & &
root - > parent_root - > parse - > setOperations ! = NULL & &
IsA ( root - > parent_root - > parse - > setOperations , SetOperationStmt ) )
qp_extra . setop =
( SetOperationStmt * ) root - > parent_root - > parse - > setOperations ;
else
qp_extra . setop = NULL ;
qp_extra . setop = setops ;
/*
* Generate the best unsorted and presorted paths for the scan / join