Thread: Way to get at parsed trigger 'WHEN' clause expression?

Way to get at parsed trigger 'WHEN' clause expression?

From
James Robinson
Date:
Folks,

    I see that psql's \d displays trigger information of a table by making a call to pg_catalog.pg_get_triggerdef(),
whichabstracts away most all need to parse the contents of system catalog pg_trigger. However, we'd like to be able to
getat a human readable representation of just the WHEN clause of the trigger expression. Function pg_get_expr() looked
likely,but fails when fed a pgqual value from pg_trigger ala: 

    ERROR: bogus varno: 2

    I suspect that it is falling over dead trying to parse the representation of NEW and / or OLD. Anything built in,
orshould we just make call to pg_catalog.pg_get_triggerdef() and parse out the WHEN clause text? 

Thanks!
------
James Robinson
Socialserve.com by Emphasys Software





Re: Way to get at parsed trigger 'WHEN' clause expression?

From
Melvin Davidson
Date:


On Thu, Mar 24, 2016 at 4:05 PM, James Robinson <jlrobins@socialserve.com> wrote:
Folks,

        I see that psql's \d displays trigger information of a table by making a call to pg_catalog.pg_get_triggerdef(), which abstracts away most all need to parse the contents of system catalog pg_trigger. However, we'd like to be able to get at a human readable representation of just the WHEN clause of the trigger expression. Function pg_get_expr() looked likely, but fails when fed a pgqual value from pg_trigger ala:

        ERROR: bogus varno: 2

        I suspect that it is falling over dead trying to parse the representation of NEW and / or OLD. Anything built in, or should we just make call to pg_catalog.pg_get_triggerdef() and parse out the WHEN clause text?

Thanks!
------
James Robinson
Socialserve.com by Emphasys Software
 

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Your problem description is a bit cloudy. Could you please give just a little more specific and provide
1. Your PostgreSQL version?
2. Your O./S ?
3. The exact trigger definition?
4. Your exact SQL query for pg_get_triggerdef() ?

Little things like that make it so much easier to provide solutions.

--
Melvin Davidson
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.

Re: Way to get at parsed trigger 'WHEN' clause expression?

From
Melvin Davidson
Date:


On Thu, Mar 24, 2016 at 6:58 PM, Melvin Davidson <melvin6925@gmail.com> wrote:


On Thu, Mar 24, 2016 at 4:05 PM, James Robinson <jlrobins@socialserve.com> wrote:
Folks,

        I see that psql's \d displays trigger information of a table by making a call to pg_catalog.pg_get_triggerdef(), which abstracts away most all need to parse the contents of system catalog pg_trigger. However, we'd like to be able to get at a human readable representation of just the WHEN clause of the trigger expression. Function pg_get_expr() looked likely, but fails when fed a pgqual value from pg_trigger ala:

        ERROR: bogus varno: 2

        I suspect that it is falling over dead trying to parse the representation of NEW and / or OLD. Anything built in, or should we just make call to pg_catalog.pg_get_triggerdef() and parse out the WHEN clause text?

Thanks!
------
James Robinson
Socialserve.com by Emphasys Software
 

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Your problem description is a bit cloudy. Could you please give just a little more specific and provide
1. Your PostgreSQL version?
2. Your O./S ?
3. The exact trigger definition?
4. Your exact SQL query for pg_get_triggerdef() ?

Little things like that make it so much easier to provide solutions.

--
Melvin Davidson
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.


Did you mean something like

SELECT substring(pg_get_triggerdef(tg.oid, TRUE) FROM position('WHEN' in pg_get_triggerdef(tg.oid, TRUE))) AS when_cond
  FROM pg_trigger tg WHERE tg.tgname = 'your_trigger_name';

--
Melvin Davidson
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.

Re: Way to get at parsed trigger 'WHEN' clause expression?

From
Melvin Davidson
Date:


On Fri, Mar 25, 2016 at 11:10 AM, Igor Neyman <ineyman@perceptron.com> wrote:

Did you mean something like

SELECT substring(pg_get_triggerdef(tg.oid, TRUE) FROM position('WHEN' in pg_get_triggerdef(tg.oid, TRUE))) AS when_cond
  FROM pg_trigger tg WHERE tg.tgname = 'your_trigger_name';


--

Melvin Davidson
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.
http://us.i1.yimg.com/us.yimg.com/i/mesg/tsmileys2/01.gif

 

 

This doesn’t answer OP question.

Besides this query gets you not only “WHEN” clause but also whatever follows it, for instance “EXECUTE PROCEDURE…”

 

As for “pg_get_expr(pg_node_tree, relation_oid)” – looks like it doesn’t work with pg_trigger, because as a second parameter (Var) it expects relation_oid, and relation could have multiple triggers, so pg_get_expr() wouldn’t know which trigger’s tgqual you want to decompile.

 

Regards,

Igor Neyman



Actually, it DOES answer the "OP" question. The "Besides" is irrelevant, as with additional length()  & position() sub functions,  just the WHEN clause can be abstracted. I'm just not going to waste my time doing all the work
when I provided a viable solution that does not error out.
--
Melvin Davidson
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.

Re: Way to get at parsed trigger 'WHEN' clause expression?

From
James Robinson
Date:
> On Mar 25, 2016, at 11:10 AM, Igor Neyman <ineyman@perceptron.com> wrote:
>
> This doesn’t answer OP question.
>
> Besides this query gets you not only “WHEN” clause but also whatever follows it, for instance “EXECUTE PROCEDURE…”

Yeah. I was imagining having to do doing something semantically equivalent, but better using some more subtle regexes.
Itsounds like folks don't know of something directly exposed at the SQL level as opposed to something available within
thebackend C only. When researching what psql's \d does, it was a pleasant surprise to see that the backend offers a
singlefunction to produce the entire trigger representation. Now alas we ended up wanting just a portion of it. 

>
> As for “pg_get_expr(pg_node_tree, relation_oid)” – looks like it doesn’t work with pg_trigger, because as a second
parameter(Var) it expects relation_oid, and relation could have multiple triggers, so pg_get_expr() wouldn’t know which
trigger’stgqual you want to decompile. 
>

pg_get_expr() can be fed the pg_catalog.pg_trigger.tgqual value, which looks to be the column where the WHERE clause
getspersisted. And then also pass in the oid of the table the trigger is on. But it seems it gets tripped up on how NEW
andOLD are represented, 'cause those are not just column references. 

I'm content with going down 'use pg_get_triggerdef(), then work to strip out all of the string contents which does not
appearto be the WHEN clause portion' for this use case (an in-house web-based schema browser which just got taught how
todisplay triggers). Was primarily interested in seeing if there was a known way of doing this short of filthy string
parsing.

I'll post the soln. I end up with just for mail archives search fodder completeness.

Thanks folks!




-------
James Robinson
james@jlr-photo.com





Re: Way to get at parsed trigger 'WHEN' clause expression?

From
James Robinson
Date:
> On Mar 25, 2016, at 3:02 PM, Igor Neyman <ineyman@perceptron.com> wrote:
>
> James,
>
> Instead of pg_catalog, you could use INFORMATION_SCHEMA to get "WHEN" clause:
>
> select action_condition from information_schema.triggers where trigger_name = 'your_trigger_name';
>
> Regards,
> Igor

Hah, good suggestion. Looking into how *it* is implemented (on 9.2 at least), brings us back to string manipulation of
theresult of pg_get_triggerdef(): 

\d+ information_schema.triggers
...
"substring"(pg_get_triggerdef(t.oid), "position"("substring"(pg_get_triggerdef(t.oid), 48), 'EXECUTE PROCEDURE'::text)
+47)::information_schema.character_data AS action_statement, 
...

But at least we can turn a blind eye to its internal horror. Thanks!

-------
James Robinson
james@jlr-photo.com





Re: Way to get at parsed trigger 'WHEN' clause expression?

From
Igor Neyman
Date:

Did you mean something like

SELECT substring(pg_get_triggerdef(tg.oid, TRUE) FROM position('WHEN' in pg_get_triggerdef(tg.oid, TRUE))) AS when_cond
  FROM pg_trigger tg WHERE tg.tgname = 'your_trigger_name';


--

Melvin Davidson
I reserve the right to fantasize.  Whether or not you
wish to share my fantasy is entirely up to you.
http://us.i1.yimg.com/us.yimg.com/i/mesg/tsmileys2/01.gif

 

 

This doesn’t answer OP question.

Besides this query gets you not only “WHEN” clause but also whatever follows it, for instance “EXECUTE PROCEDURE…”

 

As for “pg_get_expr(pg_node_tree, relation_oid)” – looks like it doesn’t work with pg_trigger, because as a second parameter (Var) it expects relation_oid, and relation could have multiple triggers, so pg_get_expr() wouldn’t know which trigger’s tgqual you want to decompile.

 

Regards,

Igor Neyman

Re: Way to get at parsed trigger 'WHEN' clause expression?

From
Igor Neyman
Date:
-----Original Message-----
From: James Robinson [mailto:jlrobins@socialserve.com] 
Sent: Friday, March 25, 2016 11:29 AM
To: Igor Neyman <ineyman@perceptron.com>
Cc: Melvin Davidson <melvin6925@gmail.com>; pgsql-general@postgresql.org
Subject: Re: [GENERAL] Way to get at parsed trigger 'WHEN' clause expression?


> On Mar 25, 2016, at 11:10 AM, Igor Neyman <ineyman@perceptron.com> wrote:
> 
> This doesn’t answer OP question.
> 
> Besides this query gets you not only “WHEN” clause but also whatever follows it, for instance “EXECUTE PROCEDURE…”

Yeah. I was imagining having to do doing something semantically equivalent, but better using some more subtle regexes.
Itsounds like folks don't know of something directly exposed at the SQL level as opposed to something available within
thebackend C only. When researching what psql's \d does, it was a pleasant surprise to see that the backend offers a
singlefunction to produce the entire trigger representation. Now alas we ended up wanting just a portion of it.
 

> 
> As for “pg_get_expr(pg_node_tree, relation_oid)” – looks like it doesn’t work with pg_trigger, because as a second
parameter(Var) it expects relation_oid, and relation could have multiple triggers, so pg_get_expr() wouldn’t know which
trigger’stgqual you want to decompile.
 
> 

pg_get_expr() can be fed the pg_catalog.pg_trigger.tgqual value, which looks to be the column where the WHERE clause
getspersisted. And then also pass in the oid of the table the trigger is on. But it seems it gets tripped up on how NEW
andOLD are represented, 'cause those are not just column references.
 

I'm content with going down 'use pg_get_triggerdef(), then work to strip out all of the string contents which does not
appearto be the WHEN clause portion' for this use case (an in-house web-based schema browser which just got taught how
todisplay triggers). Was primarily interested in seeing if there was a known way of doing this short of filthy string
parsing.

I'll post the soln. I end up with just for mail archives search fodder completeness.

Thanks folks!

-------
James Robinson
james@jlr-photo.com

_________________________________________________________________________________________________
James,

Instead of pg_catalog, you could use INFORMATION_SCHEMA to get "WHEN" clause:

select action_condition from information_schema.triggers where trigger_name = 'your_trigger_name';

Regards,
Igor