Skip to content

Commit 2f22ff3

Browse files
committed
fix issues with tlists, add description & comments
1 parent d071a30 commit 2f22ff3

File tree

1 file changed

+60
-6
lines changed

1 file changed

+60
-6
lines changed

hooks.c

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
#include "runtime_merge_append.h"
1818

1919

20+
static int cmp_tlist_vars(const void *a, const void *b);
21+
static List * sort_rel_tlist(List *tlist);
22+
2023
set_join_pathlist_hook_type set_join_pathlist_next = NULL;
2124
set_rel_pathlist_hook_type set_rel_pathlist_hook_next = NULL;
2225

23-
26+
/* Take care of joins */
2427
void
2528
pathman_join_pathlist_hook(PlannerInfo *root,
2629
RelOptInfo *joinrel,
@@ -124,9 +127,7 @@ pathman_join_pathlist_hook(PlannerInfo *root,
124127
}
125128
}
126129

127-
/*
128-
* Main hook. All the magic goes here
129-
*/
130+
/* Cope with simple relations */
130131
void
131132
pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte)
132133
{
@@ -143,7 +144,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
143144
if (!pg_pathman_enable)
144145
return;
145146

146-
/* This works only for SELECT queries */
147+
/* This works only for SELECT queries (at least for now) */
147148
if (root->parse->commandType != CMD_SELECT || !inheritance_disabled)
148149
return;
149150

@@ -153,14 +154,14 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
153154
if (prel != NULL && found)
154155
{
155156
ListCell *lc;
156-
int i;
157157
Oid *dsm_arr;
158158
List *ranges,
159159
*wrappers;
160160
PathKey *pathkeyAsc = NULL,
161161
*pathkeyDesc = NULL;
162162
double paramsel = 1.0;
163163
WalkerContext context;
164+
int i;
164165

165166
if (prel->parttype == PT_RANGE)
166167
{
@@ -252,6 +253,9 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
252253
root->simple_rte_array = new_rte_array;
253254
}
254255

256+
/* Target list should be sorted in physical order for custom nodes to work */
257+
rel->reltargetlist = sort_rel_tlist(rel->reltargetlist);
258+
255259
/*
256260
* Iterate all indexes in rangeset and append corresponding child
257261
* relations.
@@ -271,6 +275,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
271275
set_append_rel_pathlist(root, rel, rti, rte, pathkeyAsc, pathkeyDesc);
272276
set_append_rel_size(root, rel, rti, rte);
273277

278+
/* No need to go further, return */
274279
if (!(pg_pathman_enable_runtimeappend ||
275280
pg_pathman_enable_runtime_merge_append))
276281
return;
@@ -282,6 +287,7 @@ pathman_rel_pathlist_hook(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTb
282287
ParamPathInfo *ppi = get_appendrel_parampathinfo(rel, inner_required);
283288
Path *inner_path = NULL;
284289

290+
/* Skip if rel contains some join-related stuff or path type mismatched */
285291
if (!(IsA(cur_path, AppendPath) || IsA(cur_path, MergeAppendPath)) ||
286292
rel->has_eclass_joins ||
287293
rel->joininfo)
@@ -318,3 +324,51 @@ void pg_pathman_enable_assign_hook(bool newval, void *extra)
318324
"RuntimeAppend and RuntimeMergeAppend nodes have been %s",
319325
newval ? "enabled" : "disabled");
320326
}
327+
328+
/*
329+
* Sorts reltargetlist by Var's varattno (physical order) since
330+
* we can't use static build_path_tlist() for our custom nodes.
331+
*
332+
* See create_scan_plan & use_physical_tlist for more details.
333+
*/
334+
static List *
335+
sort_rel_tlist(List *tlist)
336+
{
337+
int i;
338+
int plain_tlist_size = list_length(tlist);
339+
Var **plain_tlist = palloc(plain_tlist_size * sizeof(Var *));
340+
ListCell *tlist_cell;
341+
List *result = NIL;
342+
343+
i = 0;
344+
foreach (tlist_cell, tlist)
345+
plain_tlist[i++] = lfirst(tlist_cell);
346+
347+
qsort(plain_tlist, plain_tlist_size, sizeof(Var *), cmp_tlist_vars);
348+
349+
for (i = 0; i < plain_tlist_size; i++)
350+
result = lappend(result, plain_tlist[i]);
351+
352+
return result;
353+
}
354+
355+
/* Compare Vars by varattno */
356+
static int
357+
cmp_tlist_vars(const void *a, const void *b)
358+
{
359+
Var *v1 = *(Var **) a;
360+
Var *v2 = *(Var **) b;
361+
362+
Assert(IsA(v1, Var) && IsA(v2, Var));
363+
364+
if (v1->varattno > v2->varattno)
365+
return 1;
366+
else if (v1->varattno < v2->varattno)
367+
return -1;
368+
else
369+
{
370+
/* XXX: I really doubt this case is ok */
371+
Assert(v1->varattno != v2->varattno);
372+
return 0;
373+
}
374+
}

0 commit comments

Comments
 (0)