15
15
#include "nodes/nodeFuncs.h"
16
16
#include "nodes/pg_list.h"
17
17
#include "nodes/relation.h"
18
+ #include "nodes/makefuncs.h"
18
19
#include "nodes/primnodes.h"
19
20
#include "optimizer/clauses.h"
20
21
#include "optimizer/paths.h"
38
39
#include "catalog/pg_operator.h"
39
40
#include "catalog/pg_type.h"
40
41
#include "foreign/fdwapi.h"
42
+ #include "pickyappend.h"
41
43
42
44
PG_MODULE_MAGIC ;
43
45
@@ -47,13 +49,6 @@ typedef struct
47
49
Oid new_varno ;
48
50
}change_varno_context ;
49
51
50
- typedef struct
51
- {
52
- const Node * orig ;
53
- List * args ;
54
- List * rangeset ;
55
- }WrapperNode ;
56
-
57
52
/* Original hooks */
58
53
static set_rel_pathlist_hook_type set_rel_pathlist_hook_original = NULL ;
59
54
static shmem_startup_hook_type shmem_startup_hook_original = NULL ;
@@ -79,12 +74,11 @@ static void disable_inheritance(Query *parse);
79
74
bool inheritance_disabled ;
80
75
81
76
/* Expression tree handlers */
82
- static WrapperNode * walk_expr_tree (Expr * expr ,const PartRelationInfo * prel );
83
77
static int make_hash (const PartRelationInfo * prel ,int value );
84
78
static 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 );
88
82
static void change_varnos_in_restrinct_info (RestrictInfo * rinfo ,change_varno_context * context );
89
83
static void change_varnos (Node * node ,Oid old_varno ,Oid new_varno );
90
84
static bool change_varno_walker (Node * node ,change_varno_context * context );
@@ -113,6 +107,10 @@ static void set_pathkeys(PlannerInfo *root, RelOptInfo *childrel, Path *path);
113
107
#define check_gt (flinfo ,arg1 ,arg2 ) \
114
108
((int) FunctionCall2(cmp_func, arg1, arg2) > 0)
115
109
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)) )
116
114
117
115
/*
118
116
* Entry point
@@ -136,12 +134,29 @@ _PG_init(void)
136
134
137
135
set_rel_pathlist_hook_original = set_rel_pathlist_hook ;
138
136
set_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 ;
139
139
shmem_startup_hook_original = shmem_startup_hook ;
140
140
shmem_startup_hook = pathman_shmem_startup ;
141
141
post_parse_analyze_hook_original = post_parse_analyze_hook ;
142
142
post_parse_analyze_hook = pathman_post_parse_analysis_hook ;
143
143
planner_hook_original = planner_hook ;
144
144
planner_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 ;
145
160
}
146
161
147
162
void
@@ -319,7 +334,7 @@ handle_modification_query(Query *parse)
319
334
320
335
/* Parse syntax tree and extract partition ranges */
321
336
ranges = 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 );
323
338
wrappers = lappend (wrappers ,wrap );
324
339
ranges = irange_list_intersect (ranges ,wrap -> rangeset );
325
340
@@ -395,7 +410,7 @@ pathman_set_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, Ran
395
410
396
411
RestrictInfo * rinfo = (RestrictInfo * )lfirst (lc );
397
412
398
- wrap = walk_expr_tree (rinfo -> clause ,prel );
413
+ wrap = walk_expr_tree (NULL , rinfo -> clause ,prel );
399
414
wrappers = lappend (wrappers ,wrap );
400
415
ranges = irange_list_intersect (ranges ,wrap -> rangeset );
401
416
}
@@ -708,8 +723,8 @@ change_varnos_in_restrinct_info(RestrictInfo *rinfo, change_varno_context *conte
708
723
/*
709
724
* Recursive function to walk through conditions tree
710
725
*/
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 )
713
728
{
714
729
BoolExpr * boolexpr ;
715
730
OpExpr * opexpr ;
@@ -721,15 +736,15 @@ walk_expr_tree(Expr *expr, const PartRelationInfo *prel)
721
736
/* AND, OR, NOT expressions */
722
737
case T_BoolExpr :
723
738
boolexpr = (BoolExpr * )expr ;
724
- return handle_boolexpr (boolexpr ,prel );
739
+ return handle_boolexpr (wcxt , boolexpr ,prel );
725
740
/* =, !=, <, > etc. */
726
741
case T_OpExpr :
727
742
opexpr = (OpExpr * )expr ;
728
- return handle_opexpr (opexpr ,prel );
743
+ return handle_opexpr (wcxt , opexpr ,prel );
729
744
/* IN expression */
730
745
case T_ScalarArrayOpExpr :
731
746
arrexpr = (ScalarArrayOpExpr * )expr ;
732
- return handle_arrexpr (arrexpr ,prel );
747
+ return handle_arrexpr (wcxt , arrexpr ,prel );
733
748
default :
734
749
result = (WrapperNode * )palloc (sizeof (WrapperNode ));
735
750
result -> orig = (const Node * )expr ;
@@ -813,29 +828,29 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
813
828
814
829
if ((cmp_min < 0 &&
815
830
(strategy == BTLessEqualStrategyNumber ||
816
- strategy == BTEqualStrategyNumber ))||
831
+ strategy == BTEqualStrategyNumber ))||
817
832
(cmp_min <=0 && strategy == BTLessStrategyNumber ))
818
833
{
819
834
result -> rangeset = NIL ;
820
835
return ;
821
836
}
822
837
823
- if (cmp_max >=0 && (strategy == BTGreaterEqualStrategyNumber ||
838
+ if (cmp_max >=0 && (strategy == BTGreaterEqualStrategyNumber ||
824
839
strategy == BTGreaterStrategyNumber ||
825
840
strategy == BTEqualStrategyNumber ))
826
841
{
827
842
result -> rangeset = NIL ;
828
843
return ;
829
844
}
830
845
831
- if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber )||
846
+ if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber )||
832
847
(cmp_min <=0 && strategy == BTGreaterEqualStrategyNumber ))
833
848
{
834
849
result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , false));
835
850
return ;
836
851
}
837
852
838
- if (cmp_max >=0 && (strategy == BTLessEqualStrategyNumber ||
853
+ if (cmp_max >=0 && (strategy == BTLessEqualStrategyNumber ||
839
854
strategy == BTLessStrategyNumber ))
840
855
{
841
856
result -> rangeset = list_make1_irange (make_irange (startidx ,endidx , false));
@@ -1002,11 +1017,23 @@ range_binary_search(const RangeRelation *rangerel, FmgrInfo *cmp_func, Datum val
1002
1017
return i ;
1003
1018
}
1004
1019
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
+
1005
1032
/*
1006
1033
* Operator expression handler
1007
1034
*/
1008
1035
static WrapperNode *
1009
- handle_opexpr (const OpExpr * expr ,const PartRelationInfo * prel )
1036
+ handle_opexpr (WalkerContext * wcxt , const OpExpr * expr ,const PartRelationInfo * prel )
1010
1037
{
1011
1038
WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
1012
1039
Node * firstarg = NULL ,
@@ -1020,16 +1047,16 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
1020
1047
firstarg = (Node * )linitial (expr -> args );
1021
1048
secondarg = (Node * )lsecond (expr -> args );
1022
1049
1023
- if (IsA (firstarg ,Var )&& IsA (secondarg , Const )&&
1050
+ if (IsA (firstarg ,Var )&& IsConstValue (secondarg )&&
1024
1051
((Var * )firstarg )-> varattno == prel -> attnum )
1025
1052
{
1026
- handle_binary_opexpr (prel ,result , (Var * )firstarg ,( Const * ) secondarg );
1053
+ handle_binary_opexpr (prel ,result , (Var * )firstarg ,ExtractConst ( wcxt , secondarg ) );
1027
1054
return result ;
1028
1055
}
1029
- else if (IsA (secondarg ,Var )&& IsA (firstarg , Const )&&
1056
+ else if (IsA (secondarg ,Var )&& IsConstValue (firstarg )&&
1030
1057
((Var * )secondarg )-> varattno == prel -> attnum )
1031
1058
{
1032
- handle_binary_opexpr (prel ,result , (Var * )secondarg ,( Const * ) firstarg );
1059
+ handle_binary_opexpr (prel ,result , (Var * )secondarg ,ExtractConst ( wcxt , firstarg ) );
1033
1060
return result ;
1034
1061
}
1035
1062
}
@@ -1042,7 +1069,7 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
1042
1069
* Boolean expression handler
1043
1070
*/
1044
1071
static WrapperNode *
1045
- handle_boolexpr (const BoolExpr * expr ,const PartRelationInfo * prel )
1072
+ handle_boolexpr (WalkerContext * wcxt , const BoolExpr * expr ,const PartRelationInfo * prel )
1046
1073
{
1047
1074
WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
1048
1075
ListCell * lc ;
@@ -1059,7 +1086,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
1059
1086
{
1060
1087
WrapperNode * arg ;
1061
1088
1062
- arg = walk_expr_tree ((Expr * )lfirst (lc ),prel );
1089
+ arg = walk_expr_tree (wcxt , (Expr * )lfirst (lc ),prel );
1063
1090
result -> args = lappend (result -> args ,arg );
1064
1091
switch (expr -> boolop )
1065
1092
{
@@ -1082,7 +1109,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
1082
1109
* Scalar array expression
1083
1110
*/
1084
1111
static WrapperNode *
1085
- handle_arrexpr (const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel )
1112
+ handle_arrexpr (WalkerContext * wcxt , const ScalarArrayOpExpr * expr ,const PartRelationInfo * prel )
1086
1113
{
1087
1114
WrapperNode * result = (WrapperNode * )palloc (sizeof (WrapperNode ));
1088
1115
Node * varnode = (Node * )linitial (expr -> args );