Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0207c4e

Browse files
committed
Add overseer node (not working yet
1 parent 7e76912 commit 0207c4e

9 files changed

+225
-140
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ OBJS = src/init.o src/relation_info.o src/utils.o src/partition_filter.o \
88
src/hooks.o src/nodes_common.o src/xact_handling.o src/utility_stmt_hooking.o \
99
src/planner_tree_modification.o src/debug_print.o src/partition_creation.o \
1010
src/compat/pg_compat.o src/compat/rowmarks_fix.o src/partition_router.o \
11-
$(WIN32RES)
11+
src/partition_overseer.o $(WIN32RES)
1212

1313
ifdef USE_PGXS
1414
override PG_CPPFLAGS += -I$(CURDIR)/src/include

src/hooks.c

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ planner_hook_type pathman_planner_hook_next = NULL;
6868
post_parse_analyze_hook_type pathman_post_parse_analyze_hook_next = NULL;
6969
shmem_startup_hook_type pathman_shmem_startup_hook_next = NULL;
7070
ProcessUtility_hook_type pathman_process_utility_hook_next = NULL;
71-
ExecutorRun_hook_type pathman_executor_run_hook_next = NULL;
7271

7372

7473
/* Take care of joins */
@@ -616,6 +615,29 @@ pathman_enable_assign_hook(bool newval, void *extra)
616615
newval ? "enabled" : "disabled");
617616
}
618617

618+
static void
619+
execute_for_plantree(PlannedStmt *planned_stmt,
620+
Plan *(*proc) (List *rtable, Plan *plan))
621+
{
622+
List *subplans = NIL;
623+
ListCell *lc;
624+
Plan *resplan = proc(planned_stmt->rtable, planned_stmt->planTree);
625+
626+
if (resplan)
627+
planned_stmt->planTree = resplan;
628+
629+
foreach (lc, planned_stmt->subplans)
630+
{
631+
Plan *subplan = lfirst(lc);
632+
resplan = proc(planned_stmt->rtable, (Plan *) lfirst(lc));
633+
if (resplan)
634+
subplans = lappend(subplans, resplan);
635+
else
636+
subplans = lappend(subplans, subplan);
637+
}
638+
planned_stmt->subplans = subplans;
639+
}
640+
619641
/*
620642
* Planner hook. It disables inheritance for tables that have been partitioned
621643
* by pathman to prevent standart PostgreSQL partitioning mechanism from
@@ -624,14 +646,6 @@ pathman_enable_assign_hook(bool newval, void *extra)
624646
PlannedStmt *
625647
pathman_planner_hook(Query *parse, int cursorOptions, ParamListInfo boundParams)
626648
{
627-
#define ExecuteForPlanTree(planned_stmt, proc) \
628-
do { \
629-
ListCell *lc; \
630-
proc((planned_stmt)->rtable, (planned_stmt)->planTree); \
631-
foreach (lc, (planned_stmt)->subplans) \
632-
proc((planned_stmt)->rtable, (Plan *) lfirst(lc)); \
633-
} while (0)
634-
635649
PlannedStmt *result;
636650
uint32 query_id = parse->queryId;
637651

@@ -658,10 +672,10 @@ pathman_planner_hook(Query *parse, int cursorOptions, ParamListInfo boundParams)
658672
if (pathman_ready)
659673
{
660674
/* Add PartitionFilter node for INSERT queries */
661-
ExecuteForPlanTree(result, add_partition_filters);
675+
execute_for_plantree(result, add_partition_filters);
662676

663677
/* Add PartitionRouter node for UPDATE queries */
664-
ExecuteForPlanTree(result, add_partition_routers);
678+
execute_for_plantree(result, add_partition_routers);
665679

666680
/* Decrement planner() calls count */
667681
decr_planner_calls_count();
@@ -686,7 +700,6 @@ pathman_planner_hook(Query *parse, int cursorOptions, ParamListInfo boundParams)
686700

687701
/* Finally return the Plan */
688702
return result;
689-
#undef ExecuteForPlanTree
690703
}
691704

692705
/*
@@ -950,40 +963,3 @@ pathman_process_utility_hook(Node *first_arg,
950963
context, params, queryEnv,
951964
dest, completionTag);
952965
}
953-
954-
/*
955-
* Executor hook (for PartitionRouter).
956-
*/
957-
#if PG_VERSION_NUM >= 100000
958-
void
959-
pathman_executor_hook(QueryDesc *queryDesc,
960-
ScanDirection direction,
961-
ExecutorRun_CountArgType count,
962-
bool execute_once)
963-
#else
964-
void
965-
pathman_executor_hook(QueryDesc *queryDesc,
966-
ScanDirection direction,
967-
ExecutorRun_CountArgType count)
968-
#endif
969-
{
970-
#define EXECUTOR_HOOK pathman_executor_run_hook_next
971-
#if PG_VERSION_NUM >= 100000
972-
#define EXECUTOR_HOOK_NEXT(q,d,c) EXECUTOR_HOOK((q),(d),(c), execute_once)
973-
#define EXECUTOR_RUN(q,d,c) standard_ExecutorRun((q),(d),(c), execute_once)
974-
#else
975-
#define EXECUTOR_HOOK_NEXT(q,d,c) EXECUTOR_HOOK((q),(d),(c))
976-
#define EXECUTOR_RUN(q,d,c) standard_ExecutorRun((q),(d),(c))
977-
#endif
978-
979-
/* Prepare ModifyTable nodes for PartitionRouter hackery */
980-
state_tree_visitor((PlanState *) queryDesc->planstate,
981-
prepare_modify_table_for_partition_router,
982-
NULL);
983-
984-
/* Call hooks set by other extensions if needed */
985-
if (EXECUTOR_HOOK)
986-
EXECUTOR_HOOK_NEXT(queryDesc, direction, count);
987-
/* Else call internal implementation */
988-
else EXECUTOR_RUN(queryDesc, direction, count);
989-
}

src/include/partition_overseer.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* ------------------------------------------------------------------------
2+
*
3+
* partition_overseer.h
4+
* Restart ModifyTable for unobvious reasons
5+
*
6+
* Copyright (c) 2018, Postgres Professional
7+
*
8+
* ------------------------------------------------------------------------
9+
*/
10+
11+
#ifndef PARTITION_OVERSEER_H
12+
#define PARTITION_OVERSEER_H
13+
14+
#include "relation_info.h"
15+
#include "utils.h"
16+
17+
#include "postgres.h"
18+
#include "access/tupconvert.h"
19+
#include "commands/explain.h"
20+
#include "optimizer/planner.h"
21+
22+
#if PG_VERSION_NUM >= 90600
23+
#include "nodes/extensible.h"
24+
#endif
25+
26+
27+
#define OVERSEER_NODE_NAME "PartitionOverseer"
28+
29+
30+
extern CustomScanMethods partition_overseer_plan_methods;
31+
extern CustomExecMethods partition_overseer_exec_methods;
32+
33+
34+
void init_partition_overseer_static_data(void);
35+
Plan *make_partition_overseer(Plan *subplan);
36+
37+
Node *partition_overseer_create_scan_state(CustomScan *node);
38+
39+
void partition_overseer_begin(CustomScanState *node,
40+
EState *estate,
41+
int eflags);
42+
43+
TupleTableSlot *partition_overseer_exec(CustomScanState *node);
44+
45+
void partition_overseer_end(CustomScanState *node);
46+
47+
void partition_overseer_rescan(CustomScanState *node);
48+
49+
void partition_overseer_explain(CustomScanState *node,
50+
List *ancestors,
51+
ExplainState *es);
52+
53+
54+
#endif /* PARTITION_OVERSEER_H */

src/include/partition_router.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,7 @@ extern CustomExecMethods partition_router_exec_methods;
7474

7575
void init_partition_router_static_data(void);
7676

77-
78-
Plan *make_partition_router(Plan *subplan,
79-
Oid parent_relid,
80-
Index parent_rti,
81-
int epq_param,
82-
List *returning_list);
77+
Plan *make_partition_router(Plan *subplan, int epq_param);
8378

8479
void prepare_modify_table_for_partition_router(PlanState *state, void *context);
8580

@@ -98,5 +93,6 @@ void partition_router_explain(CustomScanState *node,
9893
List *ancestors,
9994
ExplainState *es);
10095

96+
TupleTableSlot *partition_router_run_modify_table(PlanState *state);
10197

10298
#endif /* PARTITION_UPDATE_H */

src/include/planner_tree_modification.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ void assign_query_id(Query *query);
2525
void reset_query_id_generator(void);
2626

2727
/* Plan tree rewriting utility */
28-
void plan_tree_visitor(Plan *plan,
29-
void (*visitor) (Plan *plan, void *context),
28+
Plan * plan_tree_visitor(Plan *plan,
29+
Plan *(*visitor) (Plan *plan, void *context),
3030
void *context);
3131

3232
/* PlanState tree rewriting utility */
@@ -38,8 +38,8 @@ void state_tree_visitor(PlanState *state,
3838
void pathman_transform_query(Query *parse, ParamListInfo params);
3939

4040
/* These functions scribble on Plan tree */
41-
void add_partition_filters(List *rtable, Plan *plan);
42-
void add_partition_routers(List *rtable, Plan *plan);
41+
Plan *add_partition_filters(List *rtable, Plan *plan);
42+
Plan *add_partition_routers(List *rtable, Plan *plan);
4343

4444

4545
/* used by assign_rel_parenthood_status() etc */

src/partition_overseer.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
#include "postgres.h"
2+
3+
#include "partition_overseer.h"
4+
#include "partition_filter.h"
5+
#include "partition_router.h"
6+
7+
CustomScanMethods partition_overseer_plan_methods;
8+
CustomExecMethods partition_overseer_exec_methods;
9+
10+
void
11+
init_partition_overseer_static_data(void)
12+
{
13+
partition_overseer_plan_methods.CustomName = OVERSEER_NODE_NAME;
14+
partition_overseer_plan_methods.CreateCustomScanState = partition_overseer_create_scan_state;
15+
16+
partition_overseer_exec_methods.CustomName = OVERSEER_NODE_NAME;
17+
partition_overseer_exec_methods.BeginCustomScan = partition_overseer_begin;
18+
partition_overseer_exec_methods.ExecCustomScan = partition_overseer_exec;
19+
partition_overseer_exec_methods.EndCustomScan = partition_overseer_end;
20+
partition_overseer_exec_methods.ReScanCustomScan = partition_overseer_rescan;
21+
partition_overseer_exec_methods.MarkPosCustomScan = NULL;
22+
partition_overseer_exec_methods.RestrPosCustomScan = NULL;
23+
partition_overseer_exec_methods.ExplainCustomScan = partition_overseer_explain;
24+
25+
RegisterCustomScanMethods(&partition_overseer_plan_methods);
26+
}
27+
28+
Plan *
29+
make_partition_overseer(Plan *subplan)
30+
{
31+
CustomScan *cscan = makeNode(CustomScan);
32+
33+
/* Copy costs etc */
34+
cscan->scan.plan.startup_cost = subplan->startup_cost;
35+
cscan->scan.plan.total_cost = subplan->total_cost;
36+
cscan->scan.plan.plan_rows = subplan->plan_rows;
37+
cscan->scan.plan.plan_width = subplan->plan_width;
38+
39+
/* Setup methods, child plan and param number for EPQ */
40+
cscan->methods = &partition_overseer_plan_methods;
41+
cscan->custom_plans = list_make1(subplan);
42+
cscan->custom_private = NIL;
43+
44+
/* No physical relation will be scanned */
45+
cscan->scan.scanrelid = 0;
46+
47+
/* Build an appropriate target list */
48+
cscan->scan.plan.targetlist = pfilter_build_tlist(subplan);
49+
cscan->custom_scan_tlist = subplan->targetlist;
50+
51+
return &cscan->scan.plan;
52+
}
53+
54+
55+
Node *
56+
partition_overseer_create_scan_state(CustomScan *node)
57+
{
58+
CustomScanState *state = palloc0(sizeof(CustomScanState));
59+
NodeSetTag(state, T_CustomScanState);
60+
61+
state->flags = node->flags;
62+
state->methods = &partition_overseer_exec_methods;
63+
64+
return (Node *) state;
65+
}
66+
67+
void
68+
partition_overseer_begin(CustomScanState *node,
69+
EState *estate,
70+
int eflags)
71+
{
72+
CustomScan *css = (CustomScan *) node->ss.ps.plan;
73+
Plan *plan = linitial(css->custom_plans);
74+
75+
/* It's convenient to store PlanState in 'custom_ps' */
76+
node->custom_ps = list_make1(ExecInitNode(plan, estate, eflags));
77+
}
78+
79+
TupleTableSlot *
80+
partition_overseer_exec(CustomScanState *node)
81+
{
82+
PlanState *state = linitial(node->custom_ps);
83+
return partition_router_run_modify_table(state);
84+
}
85+
86+
void
87+
partition_overseer_end(CustomScanState *node)
88+
{
89+
Assert(list_length(node->custom_ps) == 1);
90+
ExecEndNode((PlanState *) linitial(node->custom_ps));
91+
}
92+
93+
void
94+
partition_overseer_rescan(CustomScanState *node)
95+
{
96+
elog(ERROR, "partition_overseer_rescan is not implemented");
97+
}
98+
99+
void
100+
partition_overseer_explain(CustomScanState *node,
101+
List *ancestors,
102+
ExplainState *es)
103+
{
104+
/* nothing to do */
105+
}

0 commit comments

Comments
 (0)