@ -49,6 +49,7 @@ typedef struct
{
{
PlannerInfo * root ;
PlannerInfo * root ;
int rtoffset ;
int rtoffset ;
double num_exec ;
} fix_scan_expr_context ;
} fix_scan_expr_context ;
typedef struct
typedef struct
@ -58,6 +59,7 @@ typedef struct
indexed_tlist * inner_itlist ;
indexed_tlist * inner_itlist ;
Index acceptable_rel ;
Index acceptable_rel ;
int rtoffset ;
int rtoffset ;
double num_exec ;
} fix_join_expr_context ;
} fix_join_expr_context ;
typedef struct
typedef struct
@ -66,8 +68,28 @@ typedef struct
indexed_tlist * subplan_itlist ;
indexed_tlist * subplan_itlist ;
Index newvarno ;
Index newvarno ;
int rtoffset ;
int rtoffset ;
double num_exec ;
} fix_upper_expr_context ;
} fix_upper_expr_context ;
/*
* Selecting the best alternative in an AlternativeSubPlan expression requires
* estimating how many times that expression will be evaluated . For an
* expression in a plan node ' s targetlist , the plan ' s estimated number of
* output rows is clearly what to use , but for an expression in a qual it ' s
* far less clear . Since AlternativeSubPlans aren ' t heavily used , we don ' t
* want to expend a lot of cycles making such estimates . What we use is twice
* the number of output rows . That ' s not entirely unfounded : we know that
* clause_selectivity ( ) would fall back to a default selectivity estimate
* of 0.5 for any SubPlan , so if the qual containing the SubPlan is the last
* to be applied ( which it likely would be , thanks to order_qual_clauses ( ) ) ,
* this matches what we could have estimated in a far more laborious fashion .
* Obviously there are many other scenarios , but it ' s probably not worth the
* trouble to try to improve on this estimate , especially not when we don ' t
* have a better estimate for the selectivity of the SubPlan qual itself .
*/
# define NUM_EXEC_TLIST(parentplan) ((parentplan)->plan_rows)
# define NUM_EXEC_QUAL(parentplan) ((parentplan)->plan_rows * 2.0)
/*
/*
* Check if a Const node is a regclass value . We accept plain OID too ,
* Check if a Const node is a regclass value . We accept plain OID too ,
* since a regclass Const will get folded to that type if it ' s an argument
* since a regclass Const will get folded to that type if it ' s an argument
@ -79,8 +101,8 @@ typedef struct
( ( ( con ) - > consttype = = REGCLASSOID | | ( con ) - > consttype = = OIDOID ) & & \
( ( ( con ) - > consttype = = REGCLASSOID | | ( con ) - > consttype = = OIDOID ) & & \
! ( con ) - > constisnull )
! ( con ) - > constisnull )
# define fix_scan_list(root, lst, rtoffset) \
# define fix_scan_list(root, lst, rtoffset, num_exec ) \
( ( List * ) fix_scan_expr ( root , ( Node * ) ( lst ) , rtoffset ) )
( ( List * ) fix_scan_expr ( root , ( Node * ) ( lst ) , rtoffset , num_exec ) )
static void add_rtes_to_flat_rtable ( PlannerInfo * root , bool recursing ) ;
static void add_rtes_to_flat_rtable ( PlannerInfo * root , bool recursing ) ;
static void flatten_unplanned_rtes ( PlannerGlobal * glob , RangeTblEntry * rte ) ;
static void flatten_unplanned_rtes ( PlannerGlobal * glob , RangeTblEntry * rte ) ;
@ -109,7 +131,8 @@ static Plan *set_mergeappend_references(PlannerInfo *root,
int rtoffset ) ;
int rtoffset ) ;
static void set_hash_references ( PlannerInfo * root , Plan * plan , int rtoffset ) ;
static void set_hash_references ( PlannerInfo * root , Plan * plan , int rtoffset ) ;
static Relids offset_relid_set ( Relids relids , int rtoffset ) ;
static Relids offset_relid_set ( Relids relids , int rtoffset ) ;
static Node * fix_scan_expr ( PlannerInfo * root , Node * node , int rtoffset ) ;
static Node * fix_scan_expr ( PlannerInfo * root , Node * node ,
int rtoffset , double num_exec ) ;
static Node * fix_scan_expr_mutator ( Node * node , fix_scan_expr_context * context ) ;
static Node * fix_scan_expr_mutator ( Node * node , fix_scan_expr_context * context ) ;
static bool fix_scan_expr_walker ( Node * node , fix_scan_expr_context * context ) ;
static bool fix_scan_expr_walker ( Node * node , fix_scan_expr_context * context ) ;
static void set_join_references ( PlannerInfo * root , Join * join , int rtoffset ) ;
static void set_join_references ( PlannerInfo * root , Join * join , int rtoffset ) ;
@ -133,14 +156,15 @@ static List *fix_join_expr(PlannerInfo *root,
List * clauses ,
List * clauses ,
indexed_tlist * outer_itlist ,
indexed_tlist * outer_itlist ,
indexed_tlist * inner_itlist ,
indexed_tlist * inner_itlist ,
Index acceptable_rel , int rtoffset ) ;
Index acceptable_rel ,
int rtoffset , double num_exec ) ;
static Node * fix_join_expr_mutator ( Node * node ,
static Node * fix_join_expr_mutator ( Node * node ,
fix_join_expr_context * context ) ;
fix_join_expr_context * context ) ;
static Node * fix_upper_expr ( PlannerInfo * root ,
static Node * fix_upper_expr ( PlannerInfo * root ,
Node * node ,
Node * node ,
indexed_tlist * subplan_itlist ,
indexed_tlist * subplan_itlist ,
Index newvarno ,
Index newvarno ,
int rtoffset ) ;
int rtoffset , double num_exec ) ;
static Node * fix_upper_expr_mutator ( Node * node ,
static Node * fix_upper_expr_mutator ( Node * node ,
fix_upper_expr_context * context ) ;
fix_upper_expr_context * context ) ;
static List * set_returning_clause_references ( PlannerInfo * root ,
static List * set_returning_clause_references ( PlannerInfo * root ,
@ -177,17 +201,20 @@ static List *set_returning_clause_references(PlannerInfo *root,
* 5. PARAM_MULTIEXPR Params are replaced by regular PARAM_EXEC Params ,
* 5. PARAM_MULTIEXPR Params are replaced by regular PARAM_EXEC Params ,
* now that we have finished planning all MULTIEXPR subplans .
* now that we have finished planning all MULTIEXPR subplans .
*
*
* 6. We compute regproc OIDs for operators ( ie , we look up the function
* 6. AlternativeSubPlan expressions are replaced by just one of their
* alternatives , using an estimate of how many times they ' ll be executed .
*
* 7. We compute regproc OIDs for operators ( ie , we look up the function
* that implements each op ) .
* that implements each op ) .
*
*
* 7. We create lists of specific objects that the plan depends on .
* 8 . We create lists of specific objects that the plan depends on .
* This will be used by plancache . c to drive invalidation of cached plans .
* This will be used by plancache . c to drive invalidation of cached plans .
* Relation dependencies are represented by OIDs , and everything else by
* Relation dependencies are represented by OIDs , and everything else by
* PlanInvalItems ( this distinction is motivated by the shared - inval APIs ) .
* PlanInvalItems ( this distinction is motivated by the shared - inval APIs ) .
* Currently , relations , user - defined functions , and domains are the only
* Currently , relations , user - defined functions , and domains are the only
* types of objects that are explicitly tracked this way .
* types of objects that are explicitly tracked this way .
*
*
* 8 . We assign every plan node in the tree a unique ID .
* 9 . We assign every plan node in the tree a unique ID .
*
*
* We also perform one final optimization step , which is to delete
* We also perform one final optimization step , which is to delete
* SubqueryScan , Append , and MergeAppend plan nodes that aren ' t doing
* SubqueryScan , Append , and MergeAppend plan nodes that aren ' t doing
@ -490,9 +517,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scanrelid + = rtoffset ;
splan - > scanrelid + = rtoffset ;
splan - > plan . targetlist =
splan - > plan . targetlist =
fix_scan_list ( root , splan - > plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > plan . qual =
splan - > plan . qual =
fix_scan_list ( root , splan - > plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_SampleScan :
case T_SampleScan :
@ -501,11 +530,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > tablesample = ( TableSampleClause * )
splan - > tablesample = ( TableSampleClause * )
fix_scan_expr ( root , ( Node * ) splan - > tablesample , rtoffset ) ;
fix_scan_expr ( root , ( Node * ) splan - > tablesample ,
rtoffset , 1 ) ;
}
}
break ;
break ;
case T_IndexScan :
case T_IndexScan :
@ -514,17 +546,23 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > indexqual =
splan - > indexqual =
fix_scan_list ( root , splan - > indexqual , rtoffset ) ;
fix_scan_list ( root , splan - > indexqual ,
rtoffset , 1 ) ;
splan - > indexqualorig =
splan - > indexqualorig =
fix_scan_list ( root , splan - > indexqualorig , rtoffset ) ;
fix_scan_list ( root , splan - > indexqualorig ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > indexorderby =
splan - > indexorderby =
fix_scan_list ( root , splan - > indexorderby , rtoffset ) ;
fix_scan_list ( root , splan - > indexorderby ,
rtoffset , 1 ) ;
splan - > indexorderbyorig =
splan - > indexorderbyorig =
fix_scan_list ( root , splan - > indexorderbyorig , rtoffset ) ;
fix_scan_list ( root , splan - > indexorderbyorig ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_IndexOnlyScan :
case T_IndexOnlyScan :
@ -543,9 +581,10 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
Assert ( splan - > scan . plan . targetlist = = NIL ) ;
Assert ( splan - > scan . plan . targetlist = = NIL ) ;
Assert ( splan - > scan . plan . qual = = NIL ) ;
Assert ( splan - > scan . plan . qual = = NIL ) ;
splan - > indexqual =
splan - > indexqual =
fix_scan_list ( root , splan - > indexqual , rtoffset ) ;
fix_scan_list ( root , splan - > indexqual , rtoffset , 1 ) ;
splan - > indexqualorig =
splan - > indexqualorig =
fix_scan_list ( root , splan - > indexqualorig , rtoffset ) ;
fix_scan_list ( root , splan - > indexqualorig ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_BitmapHeapScan :
case T_BitmapHeapScan :
@ -554,11 +593,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > bitmapqualorig =
splan - > bitmapqualorig =
fix_scan_list ( root , splan - > bitmapqualorig , rtoffset ) ;
fix_scan_list ( root , splan - > bitmapqualorig ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_TidScan :
case T_TidScan :
@ -567,11 +609,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > tidquals =
splan - > tidquals =
fix_scan_list ( root , splan - > tidquals , rtoffset ) ;
fix_scan_list ( root , splan - > tidquals ,
rtoffset , 1 ) ;
}
}
break ;
break ;
case T_SubqueryScan :
case T_SubqueryScan :
@ -585,11 +630,13 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > functions =
splan - > functions =
fix_scan_list ( root , splan - > functions , rtoffset ) ;
fix_scan_list ( root , splan - > functions , rtoffset , 1 ) ;
}
}
break ;
break ;
case T_TableFuncScan :
case T_TableFuncScan :
@ -598,11 +645,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > tablefunc = ( TableFunc * )
splan - > tablefunc = ( TableFunc * )
fix_scan_expr ( root , ( Node * ) splan - > tablefunc , rtoffset ) ;
fix_scan_expr ( root , ( Node * ) splan - > tablefunc ,
rtoffset , 1 ) ;
}
}
break ;
break ;
case T_ValuesScan :
case T_ValuesScan :
@ -611,11 +661,14 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > values_lists =
splan - > values_lists =
fix_scan_list ( root , splan - > values_lists , rtoffset ) ;
fix_scan_list ( root , splan - > values_lists ,
rtoffset , 1 ) ;
}
}
break ;
break ;
case T_CteScan :
case T_CteScan :
@ -624,9 +677,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_NamedTuplestoreScan :
case T_NamedTuplestoreScan :
@ -635,9 +690,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_WorkTableScan :
case T_WorkTableScan :
@ -646,9 +703,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . scanrelid + = rtoffset ;
splan - > scan . plan . targetlist =
splan - > scan . plan . targetlist =
fix_scan_list ( root , splan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > scan . plan . qual =
splan - > scan . plan . qual =
fix_scan_list ( root , splan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
break ;
break ;
case T_ForeignScan :
case T_ForeignScan :
@ -732,9 +791,9 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
Assert ( splan - > plan . qual = = NIL ) ;
Assert ( splan - > plan . qual = = NIL ) ;
splan - > limitOffset =
splan - > limitOffset =
fix_scan_expr ( root , splan - > limitOffset , rtoffset ) ;
fix_scan_expr ( root , splan - > limitOffset , rtoffset , 1 ) ;
splan - > limitCount =
splan - > limitCount =
fix_scan_expr ( root , splan - > limitCount , rtoffset ) ;
fix_scan_expr ( root , splan - > limitCount , rtoffset , 1 ) ;
}
}
break ;
break ;
case T_Agg :
case T_Agg :
@ -775,9 +834,9 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
* variable refs , so fix_scan_expr works for them .
* variable refs , so fix_scan_expr works for them .
*/
*/
wplan - > startOffset =
wplan - > startOffset =
fix_scan_expr ( root , wplan - > startOffset , rtoffset ) ;
fix_scan_expr ( root , wplan - > startOffset , rtoffset , 1 ) ;
wplan - > endOffset =
wplan - > endOffset =
fix_scan_expr ( root , wplan - > endOffset , rtoffset ) ;
fix_scan_expr ( root , wplan - > endOffset , rtoffset , 1 ) ;
}
}
break ;
break ;
case T_Result :
case T_Result :
@ -793,13 +852,15 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
else
else
{
{
splan - > plan . targetlist =
splan - > plan . targetlist =
fix_scan_list ( root , splan - > plan . targetlist , rtoffset ) ;
fix_scan_list ( root , splan - > plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( plan ) ) ;
splan - > plan . qual =
splan - > plan . qual =
fix_scan_list ( root , splan - > plan . qual , rtoffset ) ;
fix_scan_list ( root , splan - > plan . qual ,
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
}
}
/* resconstantqual can't contain any subplan variable refs */
/* resconstantqual can't contain any subplan variable refs */
splan - > resconstantqual =
splan - > resconstantqual =
fix_scan_expr ( root , splan - > resconstantqual , rtoffset ) ;
fix_scan_expr ( root , splan - > resconstantqual , rtoffset , 1 ) ;
}
}
break ;
break ;
case T_ProjectSet :
case T_ProjectSet :
@ -813,7 +874,8 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
Assert ( splan - > plan . qual = = NIL ) ;
Assert ( splan - > plan . qual = = NIL ) ;
splan - > withCheckOptionLists =
splan - > withCheckOptionLists =
fix_scan_list ( root , splan - > withCheckOptionLists , rtoffset ) ;
fix_scan_list ( root , splan - > withCheckOptionLists ,
rtoffset , 1 ) ;
if ( splan - > returningLists )
if ( splan - > returningLists )
{
{
@ -874,18 +936,18 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
fix_join_expr ( root , splan - > onConflictSet ,
fix_join_expr ( root , splan - > onConflictSet ,
NULL , itlist ,
NULL , itlist ,
linitial_int ( splan - > resultRelations ) ,
linitial_int ( splan - > resultRelations ) ,
rtoffset ) ;
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
splan - > onConflictWhere = ( Node * )
splan - > onConflictWhere = ( Node * )
fix_join_expr ( root , ( List * ) splan - > onConflictWhere ,
fix_join_expr ( root , ( List * ) splan - > onConflictWhere ,
NULL , itlist ,
NULL , itlist ,
linitial_int ( splan - > resultRelations ) ,
linitial_int ( splan - > resultRelations ) ,
rtoffset ) ;
rtoffset , NUM_EXEC_QUAL ( plan ) ) ;
pfree ( itlist ) ;
pfree ( itlist ) ;
splan - > exclRelTlist =
splan - > exclRelTlist =
fix_scan_list ( root , splan - > exclRelTlist , rtoffset ) ;
fix_scan_list ( root , splan - > exclRelTlist , rtoffset , 1 ) ;
}
}
splan - > nominalRelation + = rtoffset ;
splan - > nominalRelation + = rtoffset ;
@ -1026,19 +1088,24 @@ set_indexonlyscan_references(PlannerInfo *root,
( Node * ) plan - > scan . plan . targetlist ,
( Node * ) plan - > scan . plan . targetlist ,
index_itlist ,
index_itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( ( Plan * ) plan ) ) ;
plan - > scan . plan . qual = ( List * )
plan - > scan . plan . qual = ( List * )
fix_upper_expr ( root ,
fix_upper_expr ( root ,
( Node * ) plan - > scan . plan . qual ,
( Node * ) plan - > scan . plan . qual ,
index_itlist ,
index_itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) plan ) ) ;
/* indexqual is already transformed to reference index columns */
/* indexqual is already transformed to reference index columns */
plan - > indexqual = fix_scan_list ( root , plan - > indexqual , rtoffset ) ;
plan - > indexqual = fix_scan_list ( root , plan - > indexqual ,
rtoffset , 1 ) ;
/* indexorderby is already transformed to reference index columns */
/* indexorderby is already transformed to reference index columns */
plan - > indexorderby = fix_scan_list ( root , plan - > indexorderby , rtoffset ) ;
plan - > indexorderby = fix_scan_list ( root , plan - > indexorderby ,
rtoffset , 1 ) ;
/* indextlist must NOT be transformed to reference index columns */
/* indextlist must NOT be transformed to reference index columns */
plan - > indextlist = fix_scan_list ( root , plan - > indextlist , rtoffset ) ;
plan - > indextlist = fix_scan_list ( root , plan - > indextlist ,
rtoffset , NUM_EXEC_TLIST ( ( Plan * ) plan ) ) ;
pfree ( index_itlist ) ;
pfree ( index_itlist ) ;
@ -1084,9 +1151,11 @@ set_subqueryscan_references(PlannerInfo *root,
*/
*/
plan - > scan . scanrelid + = rtoffset ;
plan - > scan . scanrelid + = rtoffset ;
plan - > scan . plan . targetlist =
plan - > scan . plan . targetlist =
fix_scan_list ( root , plan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , plan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( ( Plan * ) plan ) ) ;
plan - > scan . plan . qual =
plan - > scan . plan . qual =
fix_scan_list ( root , plan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , plan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( ( Plan * ) plan ) ) ;
result = ( Plan * ) plan ;
result = ( Plan * ) plan ;
}
}
@ -1202,29 +1271,34 @@ set_foreignscan_references(PlannerInfo *root,
( Node * ) fscan - > scan . plan . targetlist ,
( Node * ) fscan - > scan . plan . targetlist ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( ( Plan * ) fscan ) ) ;
fscan - > scan . plan . qual = ( List * )
fscan - > scan . plan . qual = ( List * )
fix_upper_expr ( root ,
fix_upper_expr ( root ,
( Node * ) fscan - > scan . plan . qual ,
( Node * ) fscan - > scan . plan . qual ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) fscan ) ) ;
fscan - > fdw_exprs = ( List * )
fscan - > fdw_exprs = ( List * )
fix_upper_expr ( root ,
fix_upper_expr ( root ,
( Node * ) fscan - > fdw_exprs ,
( Node * ) fscan - > fdw_exprs ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) fscan ) ) ;
fscan - > fdw_recheck_quals = ( List * )
fscan - > fdw_recheck_quals = ( List * )
fix_upper_expr ( root ,
fix_upper_expr ( root ,
( Node * ) fscan - > fdw_recheck_quals ,
( Node * ) fscan - > fdw_recheck_quals ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) fscan ) ) ;
pfree ( itlist ) ;
pfree ( itlist ) ;
/* fdw_scan_tlist itself just needs fix_scan_list() adjustments */
/* fdw_scan_tlist itself just needs fix_scan_list() adjustments */
fscan - > fdw_scan_tlist =
fscan - > fdw_scan_tlist =
fix_scan_list ( root , fscan - > fdw_scan_tlist , rtoffset ) ;
fix_scan_list ( root , fscan - > fdw_scan_tlist ,
rtoffset , NUM_EXEC_TLIST ( ( Plan * ) fscan ) ) ;
}
}
else
else
{
{
@ -1233,13 +1307,17 @@ set_foreignscan_references(PlannerInfo *root,
* way
* way
*/
*/
fscan - > scan . plan . targetlist =
fscan - > scan . plan . targetlist =
fix_scan_list ( root , fscan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , fscan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( ( Plan * ) fscan ) ) ;
fscan - > scan . plan . qual =
fscan - > scan . plan . qual =
fix_scan_list ( root , fscan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , fscan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( ( Plan * ) fscan ) ) ;
fscan - > fdw_exprs =
fscan - > fdw_exprs =
fix_scan_list ( root , fscan - > fdw_exprs , rtoffset ) ;
fix_scan_list ( root , fscan - > fdw_exprs ,
rtoffset , NUM_EXEC_QUAL ( ( Plan * ) fscan ) ) ;
fscan - > fdw_recheck_quals =
fscan - > fdw_recheck_quals =
fix_scan_list ( root , fscan - > fdw_recheck_quals , rtoffset ) ;
fix_scan_list ( root , fscan - > fdw_recheck_quals ,
rtoffset , NUM_EXEC_QUAL ( ( Plan * ) fscan ) ) ;
}
}
fscan - > fs_relids = offset_relid_set ( fscan - > fs_relids , rtoffset ) ;
fscan - > fs_relids = offset_relid_set ( fscan - > fs_relids , rtoffset ) ;
@ -1270,33 +1348,40 @@ set_customscan_references(PlannerInfo *root,
( Node * ) cscan - > scan . plan . targetlist ,
( Node * ) cscan - > scan . plan . targetlist ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( ( Plan * ) cscan ) ) ;
cscan - > scan . plan . qual = ( List * )
cscan - > scan . plan . qual = ( List * )
fix_upper_expr ( root ,
fix_upper_expr ( root ,
( Node * ) cscan - > scan . plan . qual ,
( Node * ) cscan - > scan . plan . qual ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) cscan ) ) ;
cscan - > custom_exprs = ( List * )
cscan - > custom_exprs = ( List * )
fix_upper_expr ( root ,
fix_upper_expr ( root ,
( Node * ) cscan - > custom_exprs ,
( Node * ) cscan - > custom_exprs ,
itlist ,
itlist ,
INDEX_VAR ,
INDEX_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) cscan ) ) ;
pfree ( itlist ) ;
pfree ( itlist ) ;
/* custom_scan_tlist itself just needs fix_scan_list() adjustments */
/* custom_scan_tlist itself just needs fix_scan_list() adjustments */
cscan - > custom_scan_tlist =
cscan - > custom_scan_tlist =
fix_scan_list ( root , cscan - > custom_scan_tlist , rtoffset ) ;
fix_scan_list ( root , cscan - > custom_scan_tlist ,
rtoffset , NUM_EXEC_TLIST ( ( Plan * ) cscan ) ) ;
}
}
else
else
{
{
/* Adjust tlist, qual, custom_exprs in the standard way */
/* Adjust tlist, qual, custom_exprs in the standard way */
cscan - > scan . plan . targetlist =
cscan - > scan . plan . targetlist =
fix_scan_list ( root , cscan - > scan . plan . targetlist , rtoffset ) ;
fix_scan_list ( root , cscan - > scan . plan . targetlist ,
rtoffset , NUM_EXEC_TLIST ( ( Plan * ) cscan ) ) ;
cscan - > scan . plan . qual =
cscan - > scan . plan . qual =
fix_scan_list ( root , cscan - > scan . plan . qual , rtoffset ) ;
fix_scan_list ( root , cscan - > scan . plan . qual ,
rtoffset , NUM_EXEC_QUAL ( ( Plan * ) cscan ) ) ;
cscan - > custom_exprs =
cscan - > custom_exprs =
fix_scan_list ( root , cscan - > custom_exprs , rtoffset ) ;
fix_scan_list ( root , cscan - > custom_exprs ,
rtoffset , NUM_EXEC_QUAL ( ( Plan * ) cscan ) ) ;
}
}
/* Adjust child plan-nodes recursively, if needed */
/* Adjust child plan-nodes recursively, if needed */
@ -1458,7 +1543,8 @@ set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset)
( Node * ) hplan - > hashkeys ,
( Node * ) hplan - > hashkeys ,
outer_itlist ,
outer_itlist ,
OUTER_VAR ,
OUTER_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( plan ) ) ;
/* Hash doesn't project */
/* Hash doesn't project */
set_dummy_tlist_references ( plan , rtoffset ) ;
set_dummy_tlist_references ( plan , rtoffset ) ;
@ -1623,6 +1709,69 @@ fix_param_node(PlannerInfo *root, Param *p)
return ( Node * ) copyObject ( p ) ;
return ( Node * ) copyObject ( p ) ;
}
}
/*
* fix_alternative_subplan
* Do set_plan_references processing on an AlternativeSubPlan
*
* Choose one of the alternative implementations and return just that one ,
* discarding the rest of the AlternativeSubPlan structure .
* Note : caller must still recurse into the result !
*
* We don ' t make any attempt to fix up cost estimates in the parent plan
* node or higher - level nodes . However , we do remove the rejected subplan ( s )
* from root - > glob - > subplans , to minimize cycles expended on them later .
*/
static Node *
fix_alternative_subplan ( PlannerInfo * root , AlternativeSubPlan * asplan ,
double num_exec )
{
SubPlan * bestplan = NULL ;
Cost bestcost = 0 ;
ListCell * lc ;
/*
* Compute the estimated cost of each subplan assuming num_exec
* executions , and keep the cheapest one . Replace discarded subplans with
* NULL pointers in the global subplans list . In event of exact equality
* of estimates , we prefer the later plan ; this is a bit arbitrary , but in
* current usage it biases us to break ties against fast - start subplans .
*/
Assert ( asplan - > subplans ! = NIL ) ;
foreach ( lc , asplan - > subplans )
{
SubPlan * curplan = ( SubPlan * ) lfirst ( lc ) ;
Cost curcost ;
curcost = curplan - > startup_cost + num_exec * curplan - > per_call_cost ;
if ( bestplan = = NULL )
{
bestplan = curplan ;
bestcost = curcost ;
}
else if ( curcost < = bestcost )
{
/* drop old bestplan */
ListCell * lc2 = list_nth_cell ( root - > glob - > subplans ,
bestplan - > plan_id - 1 ) ;
lfirst ( lc2 ) = NULL ;
bestplan = curplan ;
bestcost = curcost ;
}
else
{
/* drop curplan */
ListCell * lc2 = list_nth_cell ( root - > glob - > subplans ,
curplan - > plan_id - 1 ) ;
lfirst ( lc2 ) = NULL ;
}
}
return ( Node * ) bestplan ;
}
/*
/*
* fix_scan_expr
* fix_scan_expr
* Do set_plan_references processing on a scan - level expression
* Do set_plan_references processing on a scan - level expression
@ -1630,21 +1779,24 @@ fix_param_node(PlannerInfo *root, Param *p)
* This consists of incrementing all Vars ' varnos by rtoffset ,
* This consists of incrementing all Vars ' varnos by rtoffset ,
* replacing PARAM_MULTIEXPR Params , expanding PlaceHolderVars ,
* replacing PARAM_MULTIEXPR Params , expanding PlaceHolderVars ,
* replacing Aggref nodes that should be replaced by initplan output Params ,
* replacing Aggref nodes that should be replaced by initplan output Params ,
* choosing the best implementation for AlternativeSubPlans ,
* looking up operator opcode info for OpExpr and related nodes ,
* looking up operator opcode info for OpExpr and related nodes ,
* and adding OIDs from regclass Const nodes into root - > glob - > relationOids .
* and adding OIDs from regclass Const nodes into root - > glob - > relationOids .
*/
*/
static Node *
static Node *
fix_scan_expr ( PlannerInfo * root , Node * node , int rtoffset )
fix_scan_expr ( PlannerInfo * root , Node * node , int rtoffset , double num_exec )
{
{
fix_scan_expr_context context ;
fix_scan_expr_context context ;
context . root = root ;
context . root = root ;
context . rtoffset = rtoffset ;
context . rtoffset = rtoffset ;
context . num_exec = num_exec ;
if ( rtoffset ! = 0 | |
if ( rtoffset ! = 0 | |
root - > multiexpr_params ! = NIL | |
root - > multiexpr_params ! = NIL | |
root - > glob - > lastPHId ! = 0 | |
root - > glob - > lastPHId ! = 0 | |
root - > minmax_aggs ! = NIL )
root - > minmax_aggs ! = NIL | |
root - > hasAlternativeSubPlans )
{
{
return fix_scan_expr_mutator ( node , & context ) ;
return fix_scan_expr_mutator ( node , & context ) ;
}
}
@ -1655,7 +1807,8 @@ fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset)
* are no MULTIEXPR subqueries then we don ' t need to replace
* are no MULTIEXPR subqueries then we don ' t need to replace
* PARAM_MULTIEXPR Params , and if there are no placeholders anywhere
* PARAM_MULTIEXPR Params , and if there are no placeholders anywhere
* we won ' t need to remove them , and if there are no minmax Aggrefs we
* we won ' t need to remove them , and if there are no minmax Aggrefs we
* won ' t need to replace them . Then it ' s OK to just scribble on the
* won ' t need to replace them , and if there are no AlternativeSubPlans
* we won ' t need to remove them . Then it ' s OK to just scribble on the
* input node tree instead of copying ( since the only change , filling
* input node tree instead of copying ( since the only change , filling
* in any unset opfuncid fields , is harmless ) . This saves just enough
* in any unset opfuncid fields , is harmless ) . This saves just enough
* cycles to be noticeable on trivial queries .
* cycles to be noticeable on trivial queries .
@ -1729,6 +1882,11 @@ fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context)
return fix_scan_expr_mutator ( ( Node * ) phv - > phexpr , context ) ;
return fix_scan_expr_mutator ( ( Node * ) phv - > phexpr , context ) ;
}
}
if ( IsA ( node , AlternativeSubPlan ) )
return fix_scan_expr_mutator ( fix_alternative_subplan ( context - > root ,
( AlternativeSubPlan * ) node ,
context - > num_exec ) ,
context ) ;
fix_expr_common ( context - > root , node ) ;
fix_expr_common ( context - > root , node ) ;
return expression_tree_mutator ( node , fix_scan_expr_mutator ,
return expression_tree_mutator ( node , fix_scan_expr_mutator ,
( void * ) context ) ;
( void * ) context ) ;
@ -1740,6 +1898,7 @@ fix_scan_expr_walker(Node *node, fix_scan_expr_context *context)
if ( node = = NULL )
if ( node = = NULL )
return false ;
return false ;
Assert ( ! IsA ( node , PlaceHolderVar ) ) ;
Assert ( ! IsA ( node , PlaceHolderVar ) ) ;
Assert ( ! IsA ( node , AlternativeSubPlan ) ) ;
fix_expr_common ( context - > root , node ) ;
fix_expr_common ( context - > root , node ) ;
return expression_tree_walker ( node , fix_scan_expr_walker ,
return expression_tree_walker ( node , fix_scan_expr_walker ,
( void * ) context ) ;
( void * ) context ) ;
@ -1776,7 +1935,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
outer_itlist ,
outer_itlist ,
inner_itlist ,
inner_itlist ,
( Index ) 0 ,
( Index ) 0 ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) join ) ) ;
/* Now do join-type-specific stuff */
/* Now do join-type-specific stuff */
if ( IsA ( join , NestLoop ) )
if ( IsA ( join , NestLoop ) )
@ -1792,7 +1952,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
( Node * ) nlp - > paramval ,
( Node * ) nlp - > paramval ,
outer_itlist ,
outer_itlist ,
OUTER_VAR ,
OUTER_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( outer_plan ) ) ;
/* Check we replaced any PlaceHolderVar with simple Var */
/* Check we replaced any PlaceHolderVar with simple Var */
if ( ! ( IsA ( nlp - > paramval , Var ) & &
if ( ! ( IsA ( nlp - > paramval , Var ) & &
nlp - > paramval - > varno = = OUTER_VAR ) )
nlp - > paramval - > varno = = OUTER_VAR ) )
@ -1808,7 +1969,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
outer_itlist ,
outer_itlist ,
inner_itlist ,
inner_itlist ,
( Index ) 0 ,
( Index ) 0 ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) join ) ) ;
}
}
else if ( IsA ( join , HashJoin ) )
else if ( IsA ( join , HashJoin ) )
{
{
@ -1819,7 +1981,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
outer_itlist ,
outer_itlist ,
inner_itlist ,
inner_itlist ,
( Index ) 0 ,
( Index ) 0 ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) join ) ) ;
/*
/*
* HashJoin ' s hashkeys are used to look for matching tuples from its
* HashJoin ' s hashkeys are used to look for matching tuples from its
@ -1829,7 +1992,8 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
( Node * ) hj - > hashkeys ,
( Node * ) hj - > hashkeys ,
outer_itlist ,
outer_itlist ,
OUTER_VAR ,
OUTER_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) join ) ) ;
}
}
/*
/*
@ -1867,13 +2031,15 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset)
outer_itlist ,
outer_itlist ,
inner_itlist ,
inner_itlist ,
( Index ) 0 ,
( Index ) 0 ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( ( Plan * ) join ) ) ;
join - > plan . qual = fix_join_expr ( root ,
join - > plan . qual = fix_join_expr ( root ,
join - > plan . qual ,
join - > plan . qual ,
outer_itlist ,
outer_itlist ,
inner_itlist ,
inner_itlist ,
( Index ) 0 ,
( Index ) 0 ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( ( Plan * ) join ) ) ;
pfree ( outer_itlist ) ;
pfree ( outer_itlist ) ;
pfree ( inner_itlist ) ;
pfree ( inner_itlist ) ;
@ -1926,14 +2092,16 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
( Node * ) tle - > expr ,
( Node * ) tle - > expr ,
subplan_itlist ,
subplan_itlist ,
OUTER_VAR ,
OUTER_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( plan ) ) ;
}
}
else
else
newexpr = fix_upper_expr ( root ,
newexpr = fix_upper_expr ( root ,
( Node * ) tle - > expr ,
( Node * ) tle - > expr ,
subplan_itlist ,
subplan_itlist ,
OUTER_VAR ,
OUTER_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( plan ) ) ;
tle = flatCopyTargetEntry ( tle ) ;
tle = flatCopyTargetEntry ( tle ) ;
tle - > expr = ( Expr * ) newexpr ;
tle - > expr = ( Expr * ) newexpr ;
output_targetlist = lappend ( output_targetlist , tle ) ;
output_targetlist = lappend ( output_targetlist , tle ) ;
@ -1945,7 +2113,8 @@ set_upper_references(PlannerInfo *root, Plan *plan, int rtoffset)
( Node * ) plan - > qual ,
( Node * ) plan - > qual ,
subplan_itlist ,
subplan_itlist ,
OUTER_VAR ,
OUTER_VAR ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_QUAL ( plan ) ) ;
pfree ( subplan_itlist ) ;
pfree ( subplan_itlist ) ;
}
}
@ -2389,6 +2558,7 @@ search_indexed_tlist_for_sortgroupref(Expr *node,
* ' acceptable_rel ' is either zero or the rangetable index of a relation
* ' acceptable_rel ' is either zero or the rangetable index of a relation
* whose Vars may appear in the clause without provoking an error
* whose Vars may appear in the clause without provoking an error
* ' rtoffset ' : how much to increment varnos by
* ' rtoffset ' : how much to increment varnos by
* ' num_exec ' : estimated number of executions of expression
*
*
* Returns the new expression tree . The original clause structure is
* Returns the new expression tree . The original clause structure is
* not modified .
* not modified .
@ -2399,7 +2569,8 @@ fix_join_expr(PlannerInfo *root,
indexed_tlist * outer_itlist ,
indexed_tlist * outer_itlist ,
indexed_tlist * inner_itlist ,
indexed_tlist * inner_itlist ,
Index acceptable_rel ,
Index acceptable_rel ,
int rtoffset )
int rtoffset ,
double num_exec )
{
{
fix_join_expr_context context ;
fix_join_expr_context context ;
@ -2408,6 +2579,7 @@ fix_join_expr(PlannerInfo *root,
context . inner_itlist = inner_itlist ;
context . inner_itlist = inner_itlist ;
context . acceptable_rel = acceptable_rel ;
context . acceptable_rel = acceptable_rel ;
context . rtoffset = rtoffset ;
context . rtoffset = rtoffset ;
context . num_exec = num_exec ;
return ( List * ) fix_join_expr_mutator ( ( Node * ) clauses , & context ) ;
return ( List * ) fix_join_expr_mutator ( ( Node * ) clauses , & context ) ;
}
}
@ -2502,6 +2674,11 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
/* Special cases (apply only AFTER failing to match to lower tlist) */
/* Special cases (apply only AFTER failing to match to lower tlist) */
if ( IsA ( node , Param ) )
if ( IsA ( node , Param ) )
return fix_param_node ( context - > root , ( Param * ) node ) ;
return fix_param_node ( context - > root , ( Param * ) node ) ;
if ( IsA ( node , AlternativeSubPlan ) )
return fix_join_expr_mutator ( fix_alternative_subplan ( context - > root ,
( AlternativeSubPlan * ) node ,
context - > num_exec ) ,
context ) ;
fix_expr_common ( context - > root , node ) ;
fix_expr_common ( context - > root , node ) ;
return expression_tree_mutator ( node ,
return expression_tree_mutator ( node ,
fix_join_expr_mutator ,
fix_join_expr_mutator ,
@ -2533,6 +2710,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context)
* ' subplan_itlist ' : indexed target list for subplan ( or index )
* ' subplan_itlist ' : indexed target list for subplan ( or index )
* ' newvarno ' : varno to use for Vars referencing tlist elements
* ' newvarno ' : varno to use for Vars referencing tlist elements
* ' rtoffset ' : how much to increment varnos by
* ' rtoffset ' : how much to increment varnos by
* ' num_exec ' : estimated number of executions of expression
*
*
* The resulting tree is a copy of the original in which all Var nodes have
* The resulting tree is a copy of the original in which all Var nodes have
* varno = newvarno , varattno = resno of corresponding targetlist element .
* varno = newvarno , varattno = resno of corresponding targetlist element .
@ -2543,7 +2721,8 @@ fix_upper_expr(PlannerInfo *root,
Node * node ,
Node * node ,
indexed_tlist * subplan_itlist ,
indexed_tlist * subplan_itlist ,
Index newvarno ,
Index newvarno ,
int rtoffset )
int rtoffset ,
double num_exec )
{
{
fix_upper_expr_context context ;
fix_upper_expr_context context ;
@ -2551,6 +2730,7 @@ fix_upper_expr(PlannerInfo *root,
context . subplan_itlist = subplan_itlist ;
context . subplan_itlist = subplan_itlist ;
context . newvarno = newvarno ;
context . newvarno = newvarno ;
context . rtoffset = rtoffset ;
context . rtoffset = rtoffset ;
context . num_exec = num_exec ;
return fix_upper_expr_mutator ( node , & context ) ;
return fix_upper_expr_mutator ( node , & context ) ;
}
}
@ -2623,6 +2803,11 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context)
}
}
/* If no match, just fall through to process it normally */
/* If no match, just fall through to process it normally */
}
}
if ( IsA ( node , AlternativeSubPlan ) )
return fix_upper_expr_mutator ( fix_alternative_subplan ( context - > root ,
( AlternativeSubPlan * ) node ,
context - > num_exec ) ,
context ) ;
fix_expr_common ( context - > root , node ) ;
fix_expr_common ( context - > root , node ) ;
return expression_tree_mutator ( node ,
return expression_tree_mutator ( node ,
fix_upper_expr_mutator ,
fix_upper_expr_mutator ,
@ -2687,7 +2872,8 @@ set_returning_clause_references(PlannerInfo *root,
itlist ,
itlist ,
NULL ,
NULL ,
resultRelation ,
resultRelation ,
rtoffset ) ;
rtoffset ,
NUM_EXEC_TLIST ( topplan ) ) ;
pfree ( itlist ) ;
pfree ( itlist ) ;