WIP: pushing parser hooks through SPI and plancache

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: pgsql-hackers(at)postgreSQL(dot)org
Subject: WIP: pushing parser hooks through SPI and plancache
Date: 2009-11-04 16:27:08
Message-ID: 17405.1257352028@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Attached is a draft patch for the next step in my project of
reimplementing plpgsql's parsing. This makes the recently added
parser hooks accessible for callers that are using SPI (like
plpgsql) and provides support for using such hooks in cacheable
plans. As proof of concept, plpgsql is modified to use the hooks.
plpgsql is still inserting $n symbols textually, but the "back end"
of the parsing process now goes through the ParamRef hook instead of
using a fixed parameter-type array, and then execution only fetches
actually-referenced parameters, using a hook added to ParamListInfo.

Although there's a lot left to be done, this already cures the
"if (TG_OP = 'INSERT' and NEW.foo ..." problem, as illustrated by the
changed regression test.

As I previously proposed, the core concept is to add a "meta hook"
that installs parser hook functions after a ParseState is created:
typedef void (*ParserSetupHook) (struct ParseState *pstate, void *arg);
In this way the APIs won't need to change if we add more parser hooks
later.

It turns out that this typedef is needed in two relatively low-level
.h files: nodes/params.h and utils/plancache.h. My original idea had
been to define the hook typedef in parser/parse_node.h where struct
ParseState is defined. But that would have required pulling a boatload
of parser headers into these two .h files, which seems like a bad idea
(it might even lead to circular includes). For the moment I've worked
around this by putting the typedef into nodes/params.h itself, but I
can't say I find that a pleasing solution. Has anyone got a better
idea? Should we make a parser/something header that just provides that
typedef?

BTW, the reason nodes/params.h needs it is that I added an instance
of the parser hook to ParamListInfo, which might seem a bit bizarre
since that's an execution-time data structure. The reason for this is
that we need to support things like plpgsql's
for r in explain select ...
Here, the EXPLAIN utility command is going to receive some parameters
that it has to pass down to the parsing of the command-to-explain.
So a caller that is using a parser hook needs to pass it to EXPLAIN,
and that goes through ProcessUtility and some other layers. If we
don't include the parser hook in ParamListInfo then we'll be adding
it as a separate parameter in a lot of places, and that didn't seem
to be helpful.

One other thing I'm not too happy with here is the name of this new
SPI function:

+ extern SPIPlanPtr SPI_prepare_with_hook(const char *src,
+ ParserSetupHook parserSetup,
+ void *parserSetupArg,
+ int cursorOptions);

Anybody have a better idea for that?

regards, tom lane

Attachment Content-Type Size
parser-hooks-part2.patch text/x-patch 104.3 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Chris Browne 2009-11-04 17:08:59 Re: Proposal - temporal contrib module
Previous Message Peter Eisentraut 2009-11-04 16:06:38 Re: PL/Python array support