Skip to content

Commit e841962

Browse files
committed
fixed projections in custom nodes (broken IndexOnlyScan), extract exec_append_common(), remove useless functions
1 parent 6e75ffb commit e841962

File tree

8 files changed

+105
-94
lines changed

8 files changed

+105
-94
lines changed

hooks.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,6 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
250250
root->simple_rte_array = new_rte_array;
251251
}
252252

253-
/* Target list should be sorted in physical order for custom nodes to work */
254-
rel->reltargetlist = sort_rel_tlist(rel->reltargetlist);
255-
256253
/*
257254
* Iterate all indexes in rangeset and append corresponding child
258255
* relations.

nodes_common.c

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
#include "nodes_common.h"
1313
#include "runtimeappend.h"
1414
#include "optimizer/restrictinfo.h"
15-
15+
#include "optimizer/plancat.h"
16+
#include "utils/memutils.h"
17+
#include "utils.h"
1618

1719

1820
/* Compare plans by 'original_order' */
@@ -275,6 +277,21 @@ create_append_plan_common(PlannerInfo *root, RelOptInfo *rel,
275277
RuntimeAppendPath *gpath = (RuntimeAppendPath *) best_path;
276278
CustomScan *cscan;
277279

280+
/* HACK: kill me plz, it severely breaks IndexOnlyScan */
281+
if (custom_plans)
282+
{
283+
ListCell *lc1,
284+
*lc2;
285+
286+
forboth (lc1, gpath->cpath.custom_paths, lc2, custom_plans)
287+
{
288+
Plan *child_plan = (Plan *) lfirst(lc2);
289+
RelOptInfo *child_rel = ((Path *) lfirst(lc1))->parent;
290+
291+
child_plan->targetlist = build_physical_tlist(root, child_rel);
292+
}
293+
}
294+
278295
cscan = makeNode(CustomScan);
279296
cscan->scan.plan.qual = NIL;
280297
cscan->scan.plan.targetlist = tlist;
@@ -324,6 +341,51 @@ begin_append_common(CustomScanState *node, EState *estate, int eflags)
324341
scan_state->custom_expr_states =
325342
(List *) ExecInitExpr((Expr *) scan_state->custom_exprs,
326343
(PlanState *) scan_state);
344+
345+
node->ss.ps.ps_TupFromTlist = false;
346+
}
347+
348+
TupleTableSlot *
349+
exec_append_common(CustomScanState *node,
350+
void (*fetch_next_tuple) (CustomScanState *node))
351+
{
352+
RuntimeAppendState *scan_state = (RuntimeAppendState *) node;
353+
354+
if (scan_state->ncur_plans == 0)
355+
ExecReScan(&node->ss.ps);
356+
357+
for (;;)
358+
{
359+
if (!node->ss.ps.ps_TupFromTlist)
360+
{
361+
fetch_next_tuple(node);
362+
363+
if (TupIsNull(scan_state->slot))
364+
return NULL;
365+
}
366+
367+
if (node->ss.ps.ps_ProjInfo)
368+
{
369+
ExprDoneCond isDone;
370+
TupleTableSlot *result;
371+
372+
ResetExprContext(node->ss.ps.ps_ExprContext);
373+
374+
node->ss.ps.ps_ProjInfo->pi_exprContext->ecxt_scantuple = scan_state->slot;
375+
result = ExecProject(node->ss.ps.ps_ProjInfo, &isDone);
376+
377+
if (isDone != ExprEndResult)
378+
{
379+
node->ss.ps.ps_TupFromTlist = (isDone == ExprMultipleResult);
380+
381+
return result;
382+
}
383+
else
384+
node->ss.ps.ps_TupFromTlist = false;
385+
}
386+
else
387+
return scan_state->slot;
388+
}
327389
}
328390

329391
void

nodes_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ Node * create_append_scan_state_common(CustomScan *node,
7878

7979
void begin_append_common(CustomScanState *node, EState *estate, int eflags);
8080

81+
TupleTableSlot * exec_append_common(CustomScanState *node,
82+
void (*fetch_next_tuple) (CustomScanState *node));
83+
8184
void end_append_common(CustomScanState *node);
8285

8386
void rescan_append_common(CustomScanState *node);

runtime_merge_append.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -306,17 +306,14 @@ runtimemergeappend_begin(CustomScanState *node, EState *estate, int eflags)
306306
begin_append_common(node, estate, eflags);
307307
}
308308

309-
TupleTableSlot *
310-
runtimemergeappend_exec(CustomScanState *node)
309+
static void
310+
fetch_next_tuple(CustomScanState *node)
311311
{
312312
RuntimeMergeAppendState *scan_state = (RuntimeMergeAppendState *) node;
313313
RuntimeAppendState *rstate = &scan_state->rstate;
314314
PlanState *ps;
315315
int i;
316316

317-
if (scan_state->rstate.ncur_plans == 0)
318-
ExecReScan(&node->ss.ps);
319-
320317
if (!scan_state->ms_initialized)
321318
{
322319
for (i = 0; i < scan_state->rstate.ncur_plans; i++)
@@ -367,15 +364,23 @@ runtimemergeappend_exec(CustomScanState *node)
367364
if (binaryheap_empty(scan_state->ms_heap))
368365
{
369366
/* All the subplans are exhausted, and so is the heap */
370-
return NULL;
367+
rstate->slot = NULL;
368+
return;
371369
}
372370
else
373371
{
374372
i = DatumGetInt32(binaryheap_first(scan_state->ms_heap));
375-
return scan_state->ms_slots[i];
373+
rstate->slot = scan_state->ms_slots[i];
374+
return;
376375
}
377376
}
378377

378+
TupleTableSlot *
379+
runtimemergeappend_exec(CustomScanState *node)
380+
{
381+
return exec_append_common(node, fetch_next_tuple);
382+
}
383+
379384
void
380385
runtimemergeappend_end(CustomScanState *node)
381386
{

runtimeappend.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,16 @@ runtimeappend_begin(CustomScanState *node, EState *estate, int eflags)
5858
begin_append_common(node, estate, eflags);
5959
}
6060

61-
TupleTableSlot *
62-
runtimeappend_exec(CustomScanState *node)
61+
static void
62+
fetch_next_tuple(CustomScanState *node)
6363
{
6464
RuntimeAppendState *scan_state = (RuntimeAppendState *) node;
65-
66-
if (scan_state->ncur_plans == 0)
67-
ExecReScan(&node->ss.ps);
65+
TupleTableSlot *slot = NULL;
6866

6967
while (scan_state->running_idx < scan_state->ncur_plans)
7068
{
7169
ChildScanCommon child = scan_state->cur_plans[scan_state->running_idx];
7270
PlanState *state = child->content.plan_state;
73-
TupleTableSlot *slot = NULL;
7471
bool quals;
7572

7673
for (;;)
@@ -87,15 +84,23 @@ runtimeappend_exec(CustomScanState *node)
8784
ResetExprContext(node->ss.ps.ps_ExprContext);
8885

8986
if (quals)
90-
return slot;
87+
{
88+
scan_state->slot = slot;
89+
return;
90+
}
9191
}
9292

9393
scan_state->running_idx++;
9494
}
9595

96-
/* Force ReScan */
97-
scan_state->ncur_plans = 0;
98-
return NULL;
96+
scan_state->slot = slot;
97+
return;
98+
}
99+
100+
TupleTableSlot *
101+
runtimeappend_exec(CustomScanState *node)
102+
{
103+
return exec_append_common(node, fetch_next_tuple);
99104
}
100105

101106
void

runtimeappend.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ typedef struct
4848

4949
/* Index of the selected plan state */
5050
int running_idx;
51+
52+
/* Last saved tuple (for SRF projections) */
53+
TupleTableSlot *slot;
5154
} RuntimeAppendState;
5255

5356
extern bool pg_pathman_enable_runtimeappend;

utils.c

Lines changed: 9 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -36,77 +36,16 @@ clause_contains_params_walker(Node *node, void *context)
3636
context);
3737
}
3838

39-
static Node *
40-
replace_child_var(Var *var, replace_rte_variables_context *context)
39+
static char *
40+
bms_print(Bitmapset *bms)
4141
{
42-
ReplaceVarsContext *cxt = (ReplaceVarsContext *) context->callback_arg;
43-
Var *new_var;
42+
StringInfoData str;
43+
int x;
4444

45-
new_var = makeNode(Var);
46-
memcpy(new_var, var, sizeof(Var));
45+
initStringInfo(&str);
46+
x = -1;
47+
while ((x = bms_next_member(bms, x)) >= 0)
48+
appendStringInfo(&str, " %d", x);
4749

48-
/*
49-
* Replace a partition's Var with a Var
50-
* pointing to the RuntimeAppend's results
51-
*/
52-
new_var->varno = cxt->parent->relid;
53-
new_var->location = -1;
54-
new_var->varnoold = 0;
55-
56-
return (Node *) new_var;
57-
}
58-
59-
Node *
60-
replace_child_vars_with_parent_var(Node *node, ReplaceVarsContext *context)
61-
{
62-
return replace_rte_variables(node, context->child->relid, context->sublevels_up,
63-
replace_child_var, (void *) context, NULL);
64-
}
65-
66-
/*
67-
* Sorts reltargetlist by Var's varattno (physical order) since
68-
* we can't use static build_path_tlist() for our custom nodes.
69-
*
70-
* See create_scan_plan & use_physical_tlist for more details.
71-
*/
72-
List *
73-
sort_rel_tlist(List *tlist)
74-
{
75-
int i;
76-
int plain_tlist_size = list_length(tlist);
77-
Var **plain_tlist = palloc(plain_tlist_size * sizeof(Var *));
78-
ListCell *tlist_cell;
79-
List *result = NIL;
80-
81-
i = 0;
82-
foreach (tlist_cell, tlist)
83-
plain_tlist[i++] = lfirst(tlist_cell);
84-
85-
qsort(plain_tlist, plain_tlist_size, sizeof(Var *), cmp_tlist_vars);
86-
87-
for (i = 0; i < plain_tlist_size; i++)
88-
result = lappend(result, plain_tlist[i]);
89-
90-
return result;
91-
}
92-
93-
/* Compare Vars by varattno */
94-
int
95-
cmp_tlist_vars(const void *a, const void *b)
96-
{
97-
Var *v1 = *(Var **) a;
98-
Var *v2 = *(Var **) b;
99-
100-
Assert(IsA(v1, Var) && IsA(v2, Var));
101-
102-
if (v1->varattno > v2->varattno)
103-
return 1;
104-
else if (v1->varattno < v2->varattno)
105-
return -1;
106-
else
107-
{
108-
/* XXX: I really doubt this case is ok */
109-
Assert(v1->varattno != v2->varattno);
110-
return 0;
111-
}
50+
return str.data;
11251
}

utils.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ typedef struct
2323

2424
bool clause_contains_params(Node *clause);
2525

26-
Node * replace_child_vars_with_parent_var(Node *node,
27-
ReplaceVarsContext *context);
28-
2926
int cmp_tlist_vars(const void *a, const void *b);
3027
List * sort_rel_tlist(List *tlist);
3128

0 commit comments

Comments
 (0)