Prelim specs for parser hooks for plpgsql - Mailing list pgsql-hackers
From | Tom Lane |
---|---|
Subject | Prelim specs for parser hooks for plpgsql |
Date | |
Msg-id | 1292.1256147575@sss.pgh.pa.us Whole thread Raw |
Responses |
Re: Prelim specs for parser hooks for plpgsql
|
List | pgsql-hackers |
Here's what I'm thinking of doing to enable plpgsql to resolve variable references during the main SQL parser processing, instead of its current hack of replacing references with $n in advance: 1. Add some fields to ParseState to carry hook function pointers as well as "void *" passthrough arguments for the hook functions. 2. transformColumnRef will need two hooks, a pre-transform hook and a post-transform hook. The pre-transform hook would be used to implement "old style" semantics, ie, the plpgsql variable definition takes precedence over query definition. The post hook would be used to implement either "oracle style" semantics or throwing error for conflicts. 3. The pre-transform hook would have a signature like Node *hook(ParseState *pstate, ColumnRef *cref) If it returns a node, we immediately return that as the analyzed value of the ColumnRef. If there's no hook or it returns NULL, we proceed with the normal analysis of the ColumnRef. Note: I don't see any big need to pass the "void *passthrough" argument to the hook explicitly --- if it needs it, it can fetch it out of the ParseState for itself. 4. The post-transform hook would have a signature like Node *hook(ParseState *pstate, ColumnRef *cref, Node *var) "var" is either the analyzed equivalent of the ColumnRef (usually, but not necessarily, a Var node) or NULL if the system couldn't find a referent. If "var" is NULL then the hook can return a substitute node (probably a Param), or it can return NULL to indicate that the normal no-such-column error should be thrown. If "var" is not null then the hook should either return "var", or throw error if it wants to complain that the reference is ambiguous. (We will disallow the third possibility of returning an override value when var isn't null. This is because the normal processing may have already made changes to the parse tree, which the hook won't have enough information to undo.) It will take a certain amount of code rearrangement to implement the post-transform hook --- we can't just add a call at the bottom of transformColumnRef, because we will need to retain enough state to throw the correct error if neither the core parser nor the hook can resolve the ColumnRef. This seems reasonably do-able, though the actual hook call may end up in some weird places like ParseFuncOrColumn. 5. We will also need a hook in transformParamRef() so that plpgsql can implement old-style $n references to function parameters. In this case there doesn't seem to be any real need for before/after hooks, since any given parser caller should only need p_paramtypes or a hook, not both. In fact, what I'd like to do is see if we can rip out p_paramtypes and the parser's built-in processing of ParamRefs *entirely*, and re-implement it as a hook supplied by PREPARE or Bind-message processing. So the hook would just be Node *hook(ParseState *pstate, ParamRef *pref) and the core parser would just throw error if the hook's not there or returns NULL. 6. Callers will need a way to set the hook pointers in a ParseState before invoking parsing. I think we can just have them do the equivalent steps to parse_analyze themselves, ie, call make_parsestate, set the hooks, call transformStmt, call free_parsestate; all three of those are exported already anyway. The separate entry point parse_analyze_varparams should go away entirely since the functionality it's setting up will move to hooks. 7. plpgsql will have a bit more of a problem since it's currently a couple of call levels away from the parser --- it goes through SPI. So we're going to have to modify SPI's API to some extent. I'm a bit tempted to add an entry point that lets the caller supply the parsed/analyzed/planned plantree, instead of assuming that that work must be done internally to SPI. Any thoughts about that? Any comments or objections to this plan of work? regards, tom lane
pgsql-hackers by date: