Read-only plan trees

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Subject: Read-only plan trees
Date: 2002-12-02 00:21:04
Message-ID: 2962.1038788464@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers pgsql-patches

Han Holl's recent complaint about memory leaks in SQL-language functions
has started me thinking again about making plan trees read-only to the
executor. This would make it a lot easier to manage memory cleanly in
the SQL function executor, and would eliminate a lot of plan tree
copying that currently goes on in plpgsql, prepared queries, etc.

Basically, instead of having plan tree nodes point to associated
executor state nodes, we should turn that around: executor state should
point to plan nodes. Executor startup should build a state-node tree
that exactly parallels the plan tree, and *all* data that is changed by
the executor should live in that tree. We can build this tree in a
memory context that is made to have query lifetime. At executor
shutdown, rather than individually pfree'ing lots of stuff (and having
memory leaks wherever we forget), we can just delete the query memory
context.

This is a nontrivial task, and so I plan to tackle it in several stages.

Step 1: restructure plannodes.h and execnodes.h so that there is an
executor state tree with entries for each "plan node". This tree will
be built recursively during ExecInitNode() --- you pass it a plan tree,
and it returns a state tree that links to the plan tree nodes.
ExecutorRun then needs only a pointer to the state tree.

Step 2: similarly restructure trees for expressions (quals and
targetlists). Currently we do not explicitly build a state tree for
expressions --- the objects that ought to be in this tree are the
"fcache" entries that are attached to OP_EXPR and FUNC_EXPR nodes in
an expression plan tree. The fcache objects really need to be in the
executor's context however, and the cleanest way to make that happen
seems to be to build a state tree paralleling the expression plan tree.

But this is slightly inefficient, since there would be many nodes in the
expression state trees that aren't doing anything very useful, ie, all
the ones that correspond to nodes other than OP and FUNC in the plan
tree.

An alternative approach would be to make it work somewhat like Params
do now: in each OP and FUNC node, put an integer index field to replace
the current fcache pointer. The planner would be responsible for
assigning sequential index values to every OP and FUNC in a plan, and
storing the total number of 'em in the plan's top node. Then at
runtime, the executor would allocate an array of that many fcache
structs which it'd store in the EState for the plan. Execution of
an individual op or func would index into the EState to find the fcache.

Either of these approaches would mean that we couldn't easily "just
execute" a scalar expression tree, which is something that we do in
quite a few places (constraint checking for instance). There would need
to be some advance setup done. With the Param-style approach, the
advance setup would not be read-only on the expression plan tree ...
which seems like a bad idea, so I'm leaning towards building the more
expensive data structure.

Step 3: only after all the above spadework is done could we actually set
up a query-lifetime memory context and build the executor's state in it.

Comments?

regards, tom lane

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Joe Conway 2002-12-02 01:13:01 Re: Read-only plan trees
Previous Message Justin Clift 2002-12-01 23:19:30 Re: Does anyone know what "embedded transactions" are?

Browse pgsql-patches by date

  From Date Subject
Next Message Tom Lane 2002-12-02 00:22:29 Re: contrib/adddepend does not properly re-create
Previous Message Adam Buraczewski 2002-12-02 00:14:59 Re: contrib/adddepend does not properly re-create