1515#include "nodes/nodeFuncs.h"
1616#include "nodes/pg_list.h"
1717#include "nodes/relation.h"
18+ #include "nodes/makefuncs.h"
1819#include "nodes/primnodes.h"
1920#include "optimizer/clauses.h"
2021#include "optimizer/paths.h"
3839#include "catalog/pg_operator.h"
3940#include "catalog/pg_type.h"
4041#include "foreign/fdwapi.h"
42+ #include "pickyappend.h"
4143
4244PG_MODULE_MAGIC ;
4345
@@ -47,13 +49,6 @@ typedef struct
4749Oid new_varno ;
4850}change_varno_context ;
4951
50- typedef struct
51- {
52- const Node * orig ;
53- List * args ;
54- List * rangeset ;
55- }WrapperNode ;
56-
5752/* Original hooks */
5853static set_rel_pathlist_hook_type set_rel_pathlist_hook_original = NULL ;
5954static shmem_startup_hook_type shmem_startup_hook_original = NULL ;
@@ -79,12 +74,11 @@ static void disable_inheritance(Query *parse);
7974bool inheritance_disabled ;
8075
8176/* Expression tree handlers */
82- static WrapperNode * walk_expr_tree (Expr * expr ,const PartRelationInfo * prel );
8377static int make_hash (const PartRelationInfo * prel ,int value );
8478static void handle_binary_opexpr (const PartRelationInfo * prel ,WrapperNode * result ,const Var * v ,const Const * c );
85- static WrapperNode * handle_opexpr (const OpExpr * expr ,const PartRelationInfo * prel );
86- static WrapperNode * handle_boolexpr (const BoolExpr * expr ,const PartRelationInfo * prel );
87- static WrapperNode * handle_arrexpr (const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel );
79+ static WrapperNode * handle_opexpr (WalkerContext * wcxt , const OpExpr * expr ,const PartRelationInfo * prel );
80+ static WrapperNode * handle_boolexpr (WalkerContext * wcxt , const BoolExpr * expr ,const PartRelationInfo * prel );
81+ static WrapperNode * handle_arrexpr (WalkerContext * wcxt , const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel );
8882static void change_varnos_in_restrinct_info (RestrictInfo * rinfo ,change_varno_context * context );
8983static void change_varnos (Node * node ,Oid old_varno ,Oid new_varno );
9084static bool change_varno_walker (Node * node ,change_varno_context * context );
@@ -113,6 +107,10 @@ static void set_pathkeys(PlannerInfo *root, RelOptInfo *childrel, Path *path);
113107#define check_gt (flinfo ,arg1 ,arg2 ) \
114108((int) FunctionCall2(cmp_func, arg1, arg2) > 0)
115109
110+ #define IsConstValue (node ) \
111+ ( IsA((node), Const) || IsA((node), Param) )
112+ #define ExtractConst (wcxt ,node ) \
113+ ( IsA((node), Param) ? extract_const((wcxt), (Param *) (node)) : ((Const *) (node)) )
116114
117115/*
118116 * Entry point
@@ -136,12 +134,29 @@ _PG_init(void)
136134
137135set_rel_pathlist_hook_original = set_rel_pathlist_hook ;
138136set_rel_pathlist_hook = pathman_set_rel_pathlist_hook ;
137+ set_join_pathlist_next = set_join_pathlist_hook ;
138+ set_join_pathlist_hook = pathman_join_pathlist_hook ;
139139shmem_startup_hook_original = shmem_startup_hook ;
140140shmem_startup_hook = pathman_shmem_startup ;
141141post_parse_analyze_hook_original = post_parse_analyze_hook ;
142142post_parse_analyze_hook = pathman_post_parse_analysis_hook ;
143143planner_hook_original = planner_hook ;
144144planner_hook = pathman_planner_hook ;
145+
146+ pickyappend_path_methods .CustomName = "PickyAppend" ;
147+ pickyappend_path_methods .PlanCustomPath = create_pickyappend_plan ;
148+
149+ pickyappend_plan_methods .CustomName = "PickyAppend" ;
150+ pickyappend_plan_methods .CreateCustomScanState = pickyappend_create_scan_state ;
151+
152+ pickyappend_exec_methods .CustomName = "PickyAppend" ;
153+ pickyappend_exec_methods .BeginCustomScan = pickyappend_begin ;
154+ pickyappend_exec_methods .ExecCustomScan = pickyappend_exec ;
155+ pickyappend_exec_methods .EndCustomScan = pickyappend_end ;
156+ pickyappend_exec_methods .ReScanCustomScan = pickyappend_rescan ;
157+ pickyappend_exec_methods .MarkPosCustomScan = NULL ;
158+ pickyappend_exec_methods .RestrPosCustomScan = NULL ;
159+ pickyappend_exec_methods .ExplainCustomScan = pickyppend_explain ;
145160}
146161
147162void
@@ -319,7 +334,7 @@ handle_modification_query(Query *parse)
319334
320335/* Parse syntax tree and extract partition ranges */
321336ranges = list_make1_int (make_irange (0 ,prel -> children_count - 1 , false));
322- wrap = walk_expr_tree ((Expr * )eval_const_expressions (NULL ,parse -> jointree -> quals ),prel );
337+ wrap = walk_expr_tree (NULL , (Expr * )eval_const_expressions (NULL ,parse -> jointree -> quals ),prel );
323338wrappers = lappend (wrappers ,wrap );
324339ranges = irange_list_intersect (ranges ,wrap -> rangeset );
325340
@@ -395,7 +410,7 @@ pathman_set_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, Ran
395410
396411RestrictInfo * rinfo = (RestrictInfo * )lfirst (lc );
397412
398- wrap = walk_expr_tree (rinfo -> clause ,prel );
413+ wrap = walk_expr_tree (NULL , rinfo -> clause ,prel );
399414wrappers = lappend (wrappers ,wrap );
400415ranges = irange_list_intersect (ranges ,wrap -> rangeset );
401416}
@@ -708,8 +723,8 @@ change_varnos_in_restrinct_info(RestrictInfo *rinfo, change_varno_context *conte
708723/*
709724 * Recursive function to walk through conditions tree
710725 */
711- static WrapperNode *
712- walk_expr_tree (Expr * expr ,const PartRelationInfo * prel )
726+ WrapperNode *
727+ walk_expr_tree (WalkerContext * wcxt , Expr * expr ,const PartRelationInfo * prel )
713728{
714729BoolExpr * boolexpr ;
715730OpExpr * opexpr ;
@@ -721,15 +736,15 @@ walk_expr_tree(Expr *expr, const PartRelationInfo *prel)
721736/* AND, OR, NOT expressions */
722737case T_BoolExpr :
723738boolexpr = (BoolExpr * )expr ;
724- return handle_boolexpr (boolexpr ,prel );
739+ return handle_boolexpr (wcxt , boolexpr ,prel );
725740/* =, !=, <, > etc. */
726741case T_OpExpr :
727742opexpr = (OpExpr * )expr ;
728- return handle_opexpr (opexpr ,prel );
743+ return handle_opexpr (wcxt , opexpr ,prel );
729744/* IN expression */
730745case T_ScalarArrayOpExpr :
731746arrexpr = (ScalarArrayOpExpr * )expr ;
732- return handle_arrexpr (arrexpr ,prel );
747+ return handle_arrexpr (wcxt , arrexpr ,prel );
733748default :
734749result = (WrapperNode * )palloc (sizeof (WrapperNode ));
735750result -> orig = (const Node * )expr ;
@@ -813,29 +828,29 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
813828
814829if ((cmp_min < 0 &&
815830 (strategy == BTLessEqualStrategyNumber ||
816- strategy == BTEqualStrategyNumber ))||
831+ strategy == BTEqualStrategyNumber ))||
817832(cmp_min <=0 && strategy == BTLessStrategyNumber ))
818833{
819834result -> rangeset = NIL ;
820835return ;
821836}
822837
823- if (cmp_max >=0 && (strategy == BTGreaterEqualStrategyNumber ||
838+ if (cmp_max >=0 && (strategy == BTGreaterEqualStrategyNumber ||
824839strategy == BTGreaterStrategyNumber ||
825840strategy == BTEqualStrategyNumber ))
826841{
827842result -> rangeset = NIL ;
828843return ;
829844}
830845
831- if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber )||
846+ if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber )||
832847(cmp_min <=0 && strategy == BTGreaterEqualStrategyNumber ))
833848{
834849result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , false));
835850return ;
836851}
837852
838- if (cmp_max >=0 && (strategy == BTLessEqualStrategyNumber ||
853+ if (cmp_max >=0 && (strategy == BTLessEqualStrategyNumber ||
839854strategy == BTLessStrategyNumber ))
840855{
841856result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , false));
@@ -1002,11 +1017,23 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
10021017return i ;
10031018}
10041019
1020+ static Const *
1021+ extract_const (WalkerContext * wcxt ,Param * param )
1022+ {
1023+ ExprState * estate = ExecInitExpr ((Expr * )param ,NULL );
1024+ bool isnull ;
1025+ Datum value = ExecEvalExpr (estate ,wcxt -> econtext ,& isnull ,NULL );
1026+
1027+ return makeConst (param -> paramtype ,param -> paramtypmod ,
1028+ param -> paramcollid ,get_typlen (param -> paramtype ),
1029+ value ,isnull ,get_typbyval (param -> paramtype ));
1030+ }
1031+
10051032/*
10061033 * Operator expression handler
10071034 */
10081035static WrapperNode *
1009- handle_opexpr (const OpExpr * expr ,const PartRelationInfo * prel )
1036+ handle_opexpr (WalkerContext * wcxt , const OpExpr * expr ,const PartRelationInfo * prel )
10101037{
10111038WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
10121039Node * firstarg = NULL ,
@@ -1020,16 +1047,16 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
10201047firstarg = (Node * )linitial (expr -> args );
10211048secondarg = (Node * )lsecond (expr -> args );
10221049
1023- if (IsA (firstarg ,Var )&& IsA (secondarg , Const )&&
1050+ if (IsA (firstarg ,Var )&& IsConstValue (secondarg )&&
10241051((Var * )firstarg )-> varattno == prel -> attnum )
10251052{
1026- handle_binary_opexpr (prel ,result , (Var * )firstarg ,( Const * ) secondarg );
1053+ handle_binary_opexpr (prel ,result , (Var * )firstarg ,ExtractConst ( wcxt , secondarg ) );
10271054return result ;
10281055}
1029- else if (IsA (secondarg ,Var )&& IsA (firstarg , Const )&&
1056+ else if (IsA (secondarg ,Var )&& IsConstValue (firstarg )&&
10301057 ((Var * )secondarg )-> varattno == prel -> attnum )
10311058{
1032- handle_binary_opexpr (prel ,result , (Var * )secondarg ,( Const * ) firstarg );
1059+ handle_binary_opexpr (prel ,result , (Var * )secondarg ,ExtractConst ( wcxt , firstarg ) );
10331060return result ;
10341061}
10351062}
@@ -1042,7 +1069,7 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
10421069 * Boolean expression handler
10431070 */
10441071static WrapperNode *
1045- handle_boolexpr (const BoolExpr * expr ,const PartRelationInfo * prel )
1072+ handle_boolexpr (WalkerContext * wcxt , const BoolExpr * expr ,const PartRelationInfo * prel )
10461073{
10471074WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
10481075ListCell * lc ;
@@ -1059,7 +1086,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
10591086{
10601087WrapperNode * arg ;
10611088
1062- arg = walk_expr_tree ((Expr * )lfirst (lc ),prel );
1089+ arg = walk_expr_tree (wcxt , (Expr * )lfirst (lc ),prel );
10631090result -> args = lappend (result -> args ,arg );
10641091switch (expr -> boolop )
10651092{
@@ -1082,7 +1109,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
10821109 * Scalar array expression
10831110 */
10841111static WrapperNode *
1085- handle_arrexpr (const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel )
1112+ handle_arrexpr (WalkerContext * wcxt , const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel )
10861113{
10871114WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
10881115Node * varnode = (Node * )linitial (expr -> args );