Skip to content

Commit f1e59a1

Browse files
committed
initial commit (not done yet)
1 parent 006850e commit f1e59a1

File tree

5 files changed

+459
-32
lines changed

5 files changed

+459
-32
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# contrib/pg_pathman/Makefile
22

33
MODULE_big = pg_pathman
4-
OBJS = init.o pg_pathman.o dsm_array.o rangeset.o pl_funcs.o worker.o $(WIN32RES)
4+
OBJS = init.o pickyappend.o pg_pathman.o dsm_array.o rangeset.o pl_funcs.o worker.o $(WIN32RES)
55

66
EXTENSION = pg_pathman
77
EXTVERSION = 0.1
@@ -36,4 +36,4 @@ isolationcheck: | submake-isolation
3636
$(pg_isolation_regress_check) \
3737
--temp-config=$(top_srcdir)/$(subdir)/conf.add \
3838
--outputdir=./isolation_output \
39-
$(ISOLATIONCHECKS)
39+
$(ISOLATIONCHECKS)

pathman.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "nodes/pg_list.h"
1818
#include "storage/dsm.h"
1919
#include "storage/lwlock.h"
20+
#include "nodes/primnodes.h"
21+
#include "nodes/execnodes.h"
2022

2123
/* Check PostgreSQL version */
2224
#if PG_VERSION_NUM < 90500
@@ -191,4 +193,19 @@ FmgrInfo *get_cmp_func(Oid type1, Oid type2);
191193
Oid create_partitions_bg_worker(Oid relid, Datum value, Oid value_type, bool *crashed);
192194
Oid create_partitions(Oid relid, Datum value, Oid value_type, bool *crashed);
193195

196+
typedef struct
197+
{
198+
const Node *orig;
199+
List *args;
200+
List *rangeset;
201+
} WrapperNode;
202+
203+
typedef struct
204+
{
205+
PlanState *pstate;
206+
ExprContext *econtext;
207+
} WalkerContext;
208+
209+
WrapperNode *walk_expr_tree(WalkerContext *wcxt, Expr *expr, const PartRelationInfo *prel);
210+
194211
#endif /* PATHMAN_H */

pg_pathman.c

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
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"
@@ -38,6 +39,7 @@
3839
#include "catalog/pg_operator.h"
3940
#include "catalog/pg_type.h"
4041
#include "foreign/fdwapi.h"
42+
#include "pickyappend.h"
4143

4244
PG_MODULE_MAGIC;
4345

@@ -47,13 +49,6 @@ typedef struct
4749
Oid 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 */
5853
static set_rel_pathlist_hook_type set_rel_pathlist_hook_original = NULL;
5954
static shmem_startup_hook_type shmem_startup_hook_original = NULL;
@@ -79,12 +74,11 @@ static void disable_inheritance(Query *parse);
7974
bool inheritance_disabled;
8075

8176
/* Expression tree handlers */
82-
static WrapperNode *walk_expr_tree(Expr *expr, const PartRelationInfo *prel);
8377
static int make_hash(const PartRelationInfo *prel, int value);
8478
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);
8882
static void change_varnos_in_restrinct_info(RestrictInfo *rinfo, change_varno_context *context);
8983
static void change_varnos(Node *node, Oid old_varno, Oid new_varno);
9084
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);
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

137135
set_rel_pathlist_hook_original = set_rel_pathlist_hook;
138136
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;
139139
shmem_startup_hook_original = shmem_startup_hook;
140140
shmem_startup_hook = pathman_shmem_startup;
141141
post_parse_analyze_hook_original = post_parse_analyze_hook;
142142
post_parse_analyze_hook = pathman_post_parse_analysis_hook;
143143
planner_hook_original = planner_hook;
144144
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;
145160
}
146161

147162
void
@@ -319,7 +334,7 @@ handle_modification_query(Query *parse)
319334

320335
/* Parse syntax tree and extract partition ranges */
321336
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);
323338
wrappers = lappend(wrappers, wrap);
324339
ranges = irange_list_intersect(ranges, wrap->rangeset);
325340

@@ -395,7 +410,7 @@ pathman_set_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, Ran
395410

396411
RestrictInfo *rinfo = (RestrictInfo*) lfirst(lc);
397412

398-
wrap = walk_expr_tree(rinfo->clause, prel);
413+
wrap = walk_expr_tree(NULL, rinfo->clause, prel);
399414
wrappers = lappend(wrappers, wrap);
400415
ranges = 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
{
714729
BoolExpr *boolexpr;
715730
OpExpr *opexpr;
@@ -721,15 +736,15 @@ walk_expr_tree(Expr *expr, const PartRelationInfo *prel)
721736
/* AND, OR, NOT expressions */
722737
case T_BoolExpr:
723738
boolexpr = (BoolExpr *) expr;
724-
return handle_boolexpr(boolexpr, prel);
739+
return handle_boolexpr(wcxt, boolexpr, prel);
725740
/* =, !=, <, > etc. */
726741
case T_OpExpr:
727742
opexpr = (OpExpr *) expr;
728-
return handle_opexpr(opexpr, prel);
743+
return handle_opexpr(wcxt, opexpr, prel);
729744
/* IN expression */
730745
case T_ScalarArrayOpExpr:
731746
arrexpr = (ScalarArrayOpExpr *) expr;
732-
return handle_arrexpr(arrexpr, prel);
747+
return handle_arrexpr(wcxt, arrexpr, prel);
733748
default:
734749
result = (WrapperNode *)palloc(sizeof(WrapperNode));
735750
result->orig = (const Node *)expr;
@@ -813,29 +828,29 @@ handle_binary_opexpr(const PartRelationInfo *prel, WrapperNode *result,
813828

814829
if ((cmp_min < 0 &&
815830
(strategy == BTLessEqualStrategyNumber ||
816-
strategy == BTEqualStrategyNumber)) ||
831+
strategy == BTEqualStrategyNumber)) ||
817832
(cmp_min <= 0 && strategy == BTLessStrategyNumber))
818833
{
819834
result->rangeset = NIL;
820835
return;
821836
}
822837

823-
if (cmp_max >= 0 && (strategy == BTGreaterEqualStrategyNumber ||
838+
if (cmp_max >= 0 && (strategy == BTGreaterEqualStrategyNumber ||
824839
strategy == BTGreaterStrategyNumber ||
825840
strategy == BTEqualStrategyNumber))
826841
{
827842
result->rangeset = NIL;
828843
return;
829844
}
830845

831-
if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber) ||
846+
if ((cmp_min < 0 && strategy == BTGreaterStrategyNumber) ||
832847
(cmp_min <= 0 && strategy == BTGreaterEqualStrategyNumber))
833848
{
834849
result->rangeset = list_make1_irange(make_irange(startidx, endidx, false));
835850
return;
836851
}
837852

838-
if (cmp_max >= 0 && (strategy == BTLessEqualStrategyNumber ||
853+
if (cmp_max >= 0 && (strategy == BTLessEqualStrategyNumber ||
839854
strategy == BTLessStrategyNumber))
840855
{
841856
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
10021017
return 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
*/
10081035
static WrapperNode *
1009-
handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
1036+
handle_opexpr(WalkerContext *wcxt, const OpExpr *expr, const PartRelationInfo *prel)
10101037
{
10111038
WrapperNode *result = (WrapperNode *)palloc(sizeof(WrapperNode));
10121039
Node *firstarg = NULL,
@@ -1020,16 +1047,16 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
10201047
firstarg = (Node *) linitial(expr->args);
10211048
secondarg = (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));
10271054
return 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));
10331060
return result;
10341061
}
10351062
}
@@ -1042,7 +1069,7 @@ handle_opexpr(const OpExpr *expr, const PartRelationInfo *prel)
10421069
* Boolean expression handler
10431070
*/
10441071
static WrapperNode *
1045-
handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
1072+
handle_boolexpr(WalkerContext *wcxt, const BoolExpr *expr, const PartRelationInfo *prel)
10461073
{
10471074
WrapperNode *result = (WrapperNode *)palloc(sizeof(WrapperNode));
10481075
ListCell *lc;
@@ -1059,7 +1086,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
10591086
{
10601087
WrapperNode *arg;
10611088

1062-
arg = walk_expr_tree((Expr *)lfirst(lc), prel);
1089+
arg = walk_expr_tree(wcxt, (Expr *)lfirst(lc), prel);
10631090
result->args = lappend(result->args, arg);
10641091
switch(expr->boolop)
10651092
{
@@ -1082,7 +1109,7 @@ handle_boolexpr(const BoolExpr *expr, const PartRelationInfo *prel)
10821109
* Scalar array expression
10831110
*/
10841111
static WrapperNode *
1085-
handle_arrexpr(const ScalarArrayOpExpr *expr, const PartRelationInfo *prel)
1112+
handle_arrexpr(WalkerContext *wcxt, const ScalarArrayOpExpr *expr, const PartRelationInfo *prel)
10861113
{
10871114
WrapperNode *result = (WrapperNode *)palloc(sizeof(WrapperNode));
10881115
Node *varnode = (Node *) linitial(expr->args);

0 commit comments

Comments
 (0)