Tom Lane wrote:
Uh, no, construction of a custom plan node is entirely driven by the
PlanCustomPath method as far as I can see.  You're free to ignore what
create_scan_plan did and insert your own tlist.

Are you sure? Even if it's true, this targetlist should still contain each and every Var that's been requested. If I'm correct, the only way to ensure that is to call build_path_tlist(), which is static (oops!). Perhaps I could make my own, but it uses replace_nestloop_params() (again, static), and the problem goes further and further.

This effectively means that it would be nice if I could just use the existing machinery. The fix would be quite trivial.

By the way, what if our CustomScan is a top node? Let's take a look at create_plan():

/* Recursively process the path tree, demanding the correct tlist result */
plan = create_plan_recurse(root, best_path, CP_EXACT_TLIST);

if (!IsA(plan, ModifyTable))
        apply_tlist_labeling(plan->targetlist, root->processed_tlist);

If I spoil the targetlist, everything blows up in apply_tlist_labeling():

Assert(list_length(dest_tlist) == list_length(src_tlist));

since the lengths may differ. It's much safer to use the tlist provided by the core code, but alas, sometimes it's not an option.

In particular, if what
your custom path actually is is a rescan of something like an
IndexOnlyScan, why don't you just copy the IOS's result tlist?

I'm actively working on a prototype of partition pruning. It could be much simpler if I just patched the core, but we have a working extension for 9.5 and 9.6, and we can't throw it away just yet. I wouldn't bother you if I didn't encounter a broken query :)

Dmitry Ivanov
Postgres Professional:
Russian Postgres Company

Sent via pgsql-hackers mailing list (
To make changes to your subscription:

Reply via email to