delayed initialization in worktable scan

Поиск
Список
Период
Сортировка
От Andres Freund
Тема delayed initialization in worktable scan
Дата
Msg-id 20230107213505.qx56jborg3scsngb@awork3.anarazel.de
обсуждение исходный текст
Ответы Re: delayed initialization in worktable scan  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
Hi,

while looking at fixing [1], I again came across the fact that we don't
initialize the projection etc during ExecInitWorkTableScan(), but do so during
the first call to ExecWorkTableScan().

This is explained with the following comment:

    /*
     * On the first call, find the ancestor RecursiveUnion's state via the
     * Param slot reserved for it.  (We can't do this during node init because
     * there are corner cases where we'll get the init call before the
     * RecursiveUnion does.)
     */

I remember being confused about this before. I think I dug out the relevant
commit back then 0a7abcd4c983 [2], but didn't end up finding the relevant
thread. This time I did: [3].


Basically the issue is that in queries with two CTEs we can, at least
currently, end up with a WorkTable scans on a CTE we've not yet initialized,
due to the WorkTable scan of one CTE appearing in the other. Thus
ExecInitRecursiveUnion() hasn't yet set up the param we use in
nodeWorktablescan.c to find the tuplestore and the type of the tuples it
contains.

I don't think this is a huge issue, but it surprised multiple times, so I'd
like to expand the comment. At least for me it's hard to get from "corner
cases" to one worktable scan appearing in another CTE and to mutally recursive
CTEs.


I did go down the rabbit hole of trying to avoid this issue because it "feels
wrong" to not know the return type of an executor node during initialization.
The easiest approach I could see was to add the "scan type" to WorkTableScan
(vs the target list, which includes the projection). Most of the other scan
nodes get the scan type from the underlying relation etc, and thus don't need
it in the plan node ([4]). That way the projection can be built normally
during ExecInitWorkTableScan(), but we still need to defer the lookup of
node->rustate. But that bothers me a lot less.

I'm not sure it's worth changing this. Or whether that'd be the right approach.


I'm also wondering if Tom's first instinct from back then making this an error
would have been the right call. But that ship has sailed.


To be clear, this "issue" is largely independent of [1] / not a blocker
whatsoever. Partially I wrote this to have an email to find the next time I
encounter this.

Greetings,

Andres Freund

[1] https://postgr.es/m/17737-55a063e3e6c41b4f%40postgresql.org
[2] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0a7abcd4c983
[3] https://postgr.es/m/87zllbxngg.fsf%40oxford.xeocode.com
[4] I don't particularly like that, we spend a lot of time converting memory
    inefficient target lists into tupledescs during executor initialization,
    even though we rely on the tuple types not to be materially different
    anyway. But that's a separate issue.



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Nikita Malakhov
Дата:
Сообщение: Re: How to define template types in PostgreSQL
Следующее
От: Andres Freund
Дата:
Сообщение: Re: pgsql: Delay commit status checks until freezing executes.