Thread: Access to dynamic SQL in PL/pgSQL

Access to dynamic SQL in PL/pgSQL

From
Simon Riggs
Date:
It's not currently possible to access the SQL used in a dynamic PL/pgSQL
statement using a PL/pgSQL plugin.

In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
statement type, evaluate the SQL and free memory again before the plugin
gains control again.

It seems simple to attach querystr to PLpgSQL_execstate and free it
after the plugin has seen it. The difference in lifetime of the memory
allocation is very small.

Would a patch to make this simple change be acceptable? It would need to
be backpatched to 8.1 also?

-- Simon Riggs           www.2ndQuadrant.com



Re: Access to dynamic SQL in PL/pgSQL

From
Pavel Stehule
Date:
2010/1/22 Simon Riggs <simon@2ndquadrant.com>:
>
> It's not currently possible to access the SQL used in a dynamic PL/pgSQL
> statement using a PL/pgSQL plugin.
>
> In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
> statement type, evaluate the SQL and free memory again before the plugin
> gains control again.

can you show some example, please?

Pavel

>
> It seems simple to attach querystr to PLpgSQL_execstate and free it
> after the plugin has seen it. The difference in lifetime of the memory
> allocation is very small.
>
> Would a patch to make this simple change be acceptable? It would need to
> be backpatched to 8.1 also?
>
> --
>  Simon Riggs           www.2ndQuadrant.com
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
>


Re: Access to dynamic SQL in PL/pgSQL

From
Simon Riggs
Date:
On Fri, 2010-01-22 at 11:41 +0100, Pavel Stehule wrote:
> 2010/1/22 Simon Riggs <simon@2ndquadrant.com>:
> >
> > It's not currently possible to access the SQL used in a dynamic PL/pgSQL
> > statement using a PL/pgSQL plugin.
> >
> > In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
> > statement type, evaluate the SQL and free memory again before the plugin
> > gains control again.
> 
> can you show some example, please?

exec_stmt_dynexecute() evaluates querystr at start and pfrees it before
end of exec_stmt_dynexecute(). So plugin never gets to see the SQL
executed.

-- Simon Riggs           www.2ndQuadrant.com



Re: Access to dynamic SQL in PL/pgSQL

From
Heikki Linnakangas
Date:
Simon Riggs wrote:
> It's not currently possible to access the SQL used in a dynamic PL/pgSQL
> statement using a PL/pgSQL plugin.
> 
> In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
> statement type, evaluate the SQL and free memory again before the plugin
> gains control again.
> 
> It seems simple to attach querystr to PLpgSQL_execstate and free it
> after the plugin has seen it. The difference in lifetime of the memory
> allocation is very small.

Is this for pl/debugger? How would you use the query string there?

--  Heikki Linnakangas EnterpriseDB   http://www.enterprisedb.com


Re: Access to dynamic SQL in PL/pgSQL

From
Simon Riggs
Date:
On Fri, 2010-01-22 at 13:39 +0200, Heikki Linnakangas wrote:
> Simon Riggs wrote:
> > It's not currently possible to access the SQL used in a dynamic PL/pgSQL
> > statement using a PL/pgSQL plugin.
> > 
> > In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
> > statement type, evaluate the SQL and free memory again before the plugin
> > gains control again.
> > 
> > It seems simple to attach querystr to PLpgSQL_execstate and free it
> > after the plugin has seen it. The difference in lifetime of the memory
> > allocation is very small.
> 
> Is this for pl/debugger? How would you use the query string there?

Yes, PL/debugger would have access to the text of the dynamic SQL
string.

-- Simon Riggs           www.2ndQuadrant.com



Re: Access to dynamic SQL in PL/pgSQL

From
Tom Lane
Date:
Simon Riggs <simon@2ndQuadrant.com> writes:
> It's not currently possible to access the SQL used in a dynamic PL/pgSQL
> statement using a PL/pgSQL plugin.

> In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
> statement type, evaluate the SQL and free memory again before the plugin
> gains control again.

> It seems simple to attach querystr to PLpgSQL_execstate and free it
> after the plugin has seen it. The difference in lifetime of the memory
> allocation is very small.

That seems like a complete crock --- you're talking about leaving a
dangling pointer to transient data in a permanent data structure.
In most contexts it would be difficult to be sure if the pointer was
valid or not.

If we need this it would be better to provide another plugin hook call
during the execution of a statement that uses a dynamic query.

> Would a patch to make this simple change be acceptable? It would need to
> be backpatched to 8.1 also?

As for the first, I vote "not like that", and as for backpatching,
you're out of your mind.  This would be an incompatible ABI change,
and we don't lightly make those in stable branches.  Even if we were
willing to take the risk, how would a plugin know if it were dealing
with a version of plpgsql that had this field?
        regards, tom lane


Re: Access to dynamic SQL in PL/pgSQL

From
Simon Riggs
Date:
On Fri, 2010-01-22 at 10:56 -0500, Tom Lane wrote:
> Simon Riggs <simon@2ndQuadrant.com> writes:
> > It's not currently possible to access the SQL used in a dynamic PL/pgSQL
> > statement using a PL/pgSQL plugin.
> 
> > In src/pl/plpgsql/src/pl_exec.c's exec_stmt() we call each dynamic
> > statement type, evaluate the SQL and free memory again before the plugin
> > gains control again.
> 
> > It seems simple to attach querystr to PLpgSQL_execstate and free it
> > after the plugin has seen it. The difference in lifetime of the memory
> > allocation is very small.
> 
> That seems like a complete crock --- you're talking about leaving a
> dangling pointer to transient data in a permanent data structure.

No, I wouldn't call it that. You read the bit where I said "free"?

> In most contexts it would be difficult to be sure if the pointer was
> valid or not.
> 
> If we need this it would be better to provide another plugin hook call
> during the execution of a statement that uses a dynamic query.
> 
> > Would a patch to make this simple change be acceptable? It would need to
> > be backpatched to 8.1 also?
> 
> As for the first, I vote "not like that", and as for backpatching,
> you're out of your mind.

I think by most people's standards asking for acceptance here really is
insane, I agree.

> This would be an incompatible ABI change,
> and we don't lightly make those in stable branches.  Even if we were
> willing to take the risk, how would a plugin know if it were dealing
> with a version of plpgsql that had this field?

ISTM there are ways though I think what you mean is that they would be
unpalatable.


Anyway, there already was another way of doing this, so it shall be done
that way instead. The beauty of a pluggable architecture is that one
does not need approval to implement customer solutions.

-- Simon Riggs           www.2ndQuadrant.com



Re: Access to dynamic SQL in PL/pgSQL

From
Tom Lane
Date:
Simon Riggs <simon@2ndQuadrant.com> writes:
> Anyway, there already was another way of doing this, so it shall be done
> that way instead. The beauty of a pluggable architecture is that one
> does not need approval to implement customer solutions.

If you're talking about a bundle that you're shipping to customers,
of course you can do whatever you want, since you can ensure that
your plpgsql.so and your plugin are compatible.  Stuff we release
into the wide world doesn't have that luxury.  We can't assume much
more than what PG_MODULE_MAGIC will enforce for us, and that means
ABI breaks within a major release series are dangerous.

But to get back to the point, what have you got against adding
another plugin call within the statements that build dynamic
queries?  It seems like a much cleaner solution to me, and not
any different from the standpoint of back-portability.
        regards, tom lane


Re: Access to dynamic SQL in PL/pgSQL

From
Simon Riggs
Date:
On Fri, 2010-01-22 at 11:33 -0500, Tom Lane wrote:
> Simon Riggs <simon@2ndQuadrant.com> writes:
> > Anyway, there already was another way of doing this, so it shall be done
> > that way instead. The beauty of a pluggable architecture is that one
> > does not need approval to implement customer solutions.
> 
> If you're talking about a bundle that you're shipping to customers,
> of course you can do whatever you want, since you can ensure that
> your plpgsql.so and your plugin are compatible.  

> Stuff we release
> into the wide world doesn't have that luxury.  We can't assume much
> more than what PG_MODULE_MAGIC will enforce for us, and that means
> ABI breaks within a major release series are dangerous.

Understood

> But to get back to the point, what have you got against adding
> another plugin call within the statements that build dynamic
> queries?  It seems like a much cleaner solution to me, and not
> any different from the standpoint of back-portability.

So a "dynamic query hook". When called, the hook would give access to
the query text actually executed. Existing plugins wouldn't know about
the hook, so would never call it, so the language run time would bypass
that hook altogether. Newer versions of plugins would be able to decide
whether to add-in code for the new hook based upon the version number.
Neat solution, nothing against it at all. 

Would such a solution be backpatchable? I wasn't sure what your last
sentence meant.

-- Simon Riggs           www.2ndQuadrant.com



Re: Access to dynamic SQL in PL/pgSQL

From
Tom Lane
Date:
Simon Riggs <simon@2ndQuadrant.com> writes:
> So a "dynamic query hook". When called, the hook would give access to
> the query text actually executed. Existing plugins wouldn't know about
> the hook, so would never call it, so the language run time would bypass
> that hook altogether. Newer versions of plugins would be able to decide
> whether to add-in code for the new hook based upon the version number.
> Neat solution, nothing against it at all. 

> Would such a solution be backpatchable? I wasn't sure what your last
> sentence meant.

It doesn't seem backpatchable to me, because there is no mechanism
beyond PG_MODULE_MAGIC that would ensure that plpgsql.so and the plugin
have the same idea about the contents of struct PLpgSQL_plugin.  In
hindsight it might've been a good idea if that struct contained a
version number, so if we're gonna change it I'd vote for adding one.

What my previous comment was meant to say was that this approach doesn't
seem practically different from the other as far as backwards
compatibility goes.  To wit: I don't think we can back-patch it in the
community sources, but there is nothing stopping you from back-patching
in a custom release where you have some confidence that compatible
versions of plpgsql.so and plugin will be used together.
        regards, tom lane