@@ -56,6 +56,13 @@ typedef struct
5656List * rangeset ;
5757}WrapperNode ;
5858
59+ typedef struct
60+ {
61+ const PartRelationInfo * prel ;
62+ Datum least ;
63+ Datum greatest ;
64+ }WalkerContext ;
65+
5966bool pg_pathman_enable ;
6067PathmanState * pmstate ;
6168
@@ -86,12 +93,12 @@ static void disable_inheritance_subselect(Query *parse);
8693bool inheritance_disabled ;
8794
8895/* Expression tree handlers */
89- static WrapperNode * walk_expr_tree (Expr * expr ,const PartRelationInfo * prel );
96+ static WrapperNode * walk_expr_tree (Expr * expr ,WalkerContext * context );
9097static int make_hash (const PartRelationInfo * prel ,int value );
91- static void handle_binary_opexpr (const PartRelationInfo * prel ,WrapperNode * result ,const Var * v ,const Const * c );
92- static WrapperNode * handle_opexpr (const OpExpr * expr ,const PartRelationInfo * prel );
93- static WrapperNode * handle_boolexpr (const BoolExpr * expr ,const PartRelationInfo * prel );
94- static WrapperNode * handle_arrexpr (const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel );
98+ static void handle_binary_opexpr (WalkerContext * context ,WrapperNode * result ,const Var * v ,const Const * c );
99+ static WrapperNode * handle_opexpr (const OpExpr * expr ,WalkerContext * context );
100+ static WrapperNode * handle_boolexpr (const BoolExpr * expr ,WalkerContext * context );
101+ static WrapperNode * handle_arrexpr (const ScalarArrayOpExpr * expr ,WalkerContext * context );
95102static void change_varnos_in_restrinct_info (RestrictInfo * rinfo ,change_varno_context * context );
96103static void change_varnos (Node * node ,Oid old_varno ,Oid new_varno );
97104static bool change_varno_walker (Node * node ,change_varno_context * context );
@@ -359,12 +366,13 @@ disable_inheritance_subselect(Query *parse)
359366static void
360367handle_modification_query (Query * parse )
361368{
362- PartRelationInfo * prel ;
363- List * ranges ;
364- RangeTblEntry * rte ;
365- WrapperNode * wrap ;
366- Expr * expr ;
367- bool found ;
369+ PartRelationInfo * prel ;
370+ List * ranges ;
371+ RangeTblEntry * rte ;
372+ WrapperNode * wrap ;
373+ Expr * expr ;
374+ bool found ;
375+ WalkerContext context ;
368376
369377Assert (parse -> commandType == CMD_UPDATE ||
370378parse -> commandType == CMD_DELETE );
@@ -383,7 +391,8 @@ handle_modification_query(Query *parse)
383391return ;
384392
385393/* Parse syntax tree and extract partition ranges */
386- wrap = walk_expr_tree (expr ,prel );
394+ context .prel = prel ;
395+ wrap = walk_expr_tree (expr ,& context );
387396ranges = irange_list_intersect (ranges ,wrap -> rangeset );
388397
389398/* If only one partition is affected then substitute parent table with partition */
@@ -424,11 +433,11 @@ pathman_shmem_startup(void)
424433void
425434pathman_set_rel_pathlist_hook (PlannerInfo * root ,RelOptInfo * rel ,Index rti ,RangeTblEntry * rte )
426435{
427- PartRelationInfo * prel = NULL ;
428- RelOptInfo * * new_rel_array ;
429- RangeTblEntry * * new_rte_array ;
430- int len ;
431- bool found ;
436+ PartRelationInfo * prel = NULL ;
437+ RelOptInfo * * new_rel_array ;
438+ RangeTblEntry * * new_rte_array ;
439+ int len ;
440+ bool found ;
432441
433442/* Invoke original hook if needed */
434443if (set_rel_pathlist_hook_original != NULL )
@@ -497,11 +506,13 @@ pathman_set_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, Ran
497506wrappers = NIL ;
498507foreach (lc ,rel -> baserestrictinfo )
499508{
500- WrapperNode * wrap ;
509+ WrapperNode * wrap ;
510+ WalkerContext context ;
501511
502512RestrictInfo * rinfo = (RestrictInfo * )lfirst (lc );
503513
504- wrap = walk_expr_tree (rinfo -> clause ,prel );
514+ context .prel = prel ;
515+ wrap = walk_expr_tree (rinfo -> clause ,& context );
505516wrappers = lappend (wrappers ,wrap );
506517ranges = irange_list_intersect (ranges ,wrap -> rangeset );
507518}
@@ -523,11 +534,11 @@ pathman_set_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, Ran
523534palloc0 ((root -> simple_rel_array_size + len )* sizeof (RangeTblEntry * ));
524535
525536/* Copy relations to the new arrays */
526- for (i = 0 ;i < root -> simple_rel_array_size ;i ++ )
527- {
528- new_rel_array [i ]= root -> simple_rel_array [i ];
529- new_rte_array [i ]= root -> simple_rte_array [i ];
530- }
537+ for (i = 0 ;i < root -> simple_rel_array_size ;i ++ )
538+ {
539+ new_rel_array [i ]= root -> simple_rel_array [i ];
540+ new_rte_array [i ]= root -> simple_rte_array [i ];
541+ }
531542
532543/* Free old arrays */
533544pfree (root -> simple_rel_array );
@@ -564,8 +575,8 @@ static void
564575set_append_rel_size (PlannerInfo * root ,RelOptInfo * rel ,
565576Index rti ,RangeTblEntry * rte )
566577{
567- double parent_rows = 0 ;
568- double parent_size = 0 ;
578+ double parent_rows = 0 ;
579+ double parent_size = 0 ;
569580ListCell * l ;
570581
571582foreach (l ,root -> append_rel_list )
@@ -943,7 +954,7 @@ change_varnos_in_restrinct_info(RestrictInfo *rinfo, change_varno_context *conte
943954 * Recursive function to walk through conditions tree
944955 */
945956static WrapperNode *
946- walk_expr_tree (Expr * expr ,const PartRelationInfo * prel )
957+ walk_expr_tree (Expr * expr ,WalkerContext * context )
947958{
948959BoolExpr * boolexpr ;
949960OpExpr * opexpr ;
@@ -955,20 +966,20 @@ walk_expr_tree(Expr *expr, const PartRelationInfo *prel)
955966/* AND, OR, NOT expressions */
956967case T_BoolExpr :
957968boolexpr = (BoolExpr * )expr ;
958- return handle_boolexpr (boolexpr ,prel );
969+ return handle_boolexpr (boolexpr ,context );
959970/* =, !=, <, > etc. */
960971case T_OpExpr :
961972opexpr = (OpExpr * )expr ;
962- return handle_opexpr (opexpr ,prel );
973+ return handle_opexpr (opexpr ,context );
963974/* IN expression */
964975case T_ScalarArrayOpExpr :
965976arrexpr = (ScalarArrayOpExpr * )expr ;
966- return handle_arrexpr (arrexpr ,prel );
977+ return handle_arrexpr (arrexpr ,context );
967978default :
968979result = (WrapperNode * )palloc (sizeof (WrapperNode ));
969980result -> orig = (const Node * )expr ;
970981result -> args = NIL ;
971- result -> rangeset = list_make1_irange (make_irange (0 ,prel -> children_count - 1 , true));
982+ result -> rangeset = list_make1_irange (make_irange (0 ,context -> prel -> children_count - 1 , true));
972983return result ;
973984}
974985}
@@ -977,7 +988,7 @@ walk_expr_tree(Expr *expr, const PartRelationInfo *prel)
977988 *This function determines which partitions should appear in query plan
978989 */
979990static void
980- handle_binary_opexpr (const PartRelationInfo * prel ,WrapperNode * result ,
991+ handle_binary_opexpr (WalkerContext * context ,WrapperNode * result ,
981992const Var * v ,const Const * c )
982993{
983994HashRelationKey key ;
@@ -992,6 +1003,7 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
9921003Oid cmp_proc_oid ;
9931004const OpExpr * expr = (const OpExpr * )result -> orig ;
9941005TypeCacheEntry * tce ;
1006+ const PartRelationInfo * prel = context -> prel ;
9951007
9961008/* Determine operator type */
9971009tce = lookup_type_cache (v -> vartype ,
@@ -1240,11 +1252,12 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
12401252 * Operator expression handler
12411253 */
12421254static WrapperNode *
1243- handle_opexpr (const OpExpr * expr ,const PartRelationInfo * prel )
1255+ handle_opexpr (const OpExpr * expr ,WalkerContext * context )
12441256{
12451257WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
12461258Node * firstarg = NULL ,
12471259* secondarg = NULL ;
1260+ const PartRelationInfo * prel = context -> prel ;
12481261
12491262result -> orig = (const Node * )expr ;
12501263result -> args = NIL ;
@@ -1257,13 +1270,13 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
12571270if (IsA (firstarg ,Var )&& IsA (secondarg ,Const )&&
12581271((Var * )firstarg )-> varattno == prel -> attnum )
12591272{
1260- handle_binary_opexpr (prel ,result , (Var * )firstarg , (Const * )secondarg );
1273+ handle_binary_opexpr (context ,result , (Var * )firstarg , (Const * )secondarg );
12611274return result ;
12621275}
12631276else if (IsA (secondarg ,Var )&& IsA (firstarg ,Const )&&
12641277 ((Var * )secondarg )-> varattno == prel -> attnum )
12651278{
1266- handle_binary_opexpr (prel ,result , (Var * )secondarg , (Const * )firstarg );
1279+ handle_binary_opexpr (context ,result , (Var * )secondarg , (Const * )firstarg );
12671280return result ;
12681281}
12691282}
@@ -1276,10 +1289,11 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
12761289 * Boolean expression handler
12771290 */
12781291static WrapperNode *
1279- handle_boolexpr (const BoolExpr * expr ,const PartRelationInfo * prel )
1292+ handle_boolexpr (const BoolExpr * expr ,WalkerContext * context )
12801293{
12811294WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
12821295ListCell * lc ;
1296+ const PartRelationInfo * prel = context -> prel ;
12831297
12841298result -> orig = (const Node * )expr ;
12851299result -> args = NIL ;
@@ -1293,7 +1307,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
12931307{
12941308WrapperNode * arg ;
12951309
1296- arg = walk_expr_tree ((Expr * )lfirst (lc ),prel );
1310+ arg = walk_expr_tree ((Expr * )lfirst (lc ),context );
12971311result -> args = lappend (result -> args ,arg );
12981312switch (expr -> boolop )
12991313{
@@ -1316,12 +1330,13 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
13161330 * Scalar array expression
13171331 */
13181332static WrapperNode *
1319- handle_arrexpr (const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel )
1333+ handle_arrexpr (const ScalarArrayOpExpr * expr ,WalkerContext * context )
13201334{
13211335WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
13221336Node * varnode = (Node * )linitial (expr -> args );
13231337Node * arraynode = (Node * )lsecond (expr -> args );
13241338int hash ;
1339+ const PartRelationInfo * prel = context -> prel ;
13251340
13261341result -> orig = (const Node * )expr ;
13271342result -> args = NIL ;