Thread
-
UPDATE SET (a,b,c) = (SELECT ...) versus rules
Tom Lane <tgl@sss.pgh.pa.us> — 2014-06-14T19:35:33Z
As I mentioned awhile ago, I'm thinking about implementing the SQL-standard construct UPDATE foo SET ..., (a,b,...) = (SELECT x,y,...), ... I've run into a rather nasty problem, which is how does this interact with expansion of NEW references in ON UPDATE rules? For example, suppose foo has a rule ON UPDATE DO ALSO INSERT INTO foolog VALUES (new.a, new.b, ...); The existing implementation relies on being able to pull expressions for individual fields' new values out of the UPDATE targetlist; but there is no independent expression for the new value of "a" here. Worse yet, the NEW references might be in WHERE quals, or some other place outside the targetlist of the rule query, which pretty much breaks the implementation I'd sketched earlier. The best that I think is reasonable to do in such cases is to pull out a separate copy of the sub-select for each actual NEW reference in a rule query. So the example above would give rise to an expanded rule query along the lines of INSERT INTO foolog VALUES ( (SELECT x as a, y as b, ...).a, (SELECT x as a, y as b, ...).b, ... ); which would work, but it would re-evaluate the sub-select more times than the user might be hoping. (Of course, if there are volatile functions in the sub-select, he's screwed, but that's not a new problem with rules.) Given that ON UPDATE rules are close to being a deprecated feature, it doesn't seem appropriate to work harder than this; and frankly I don't see how we could avoid multiple sub-select evaluations anyway, if the NEW references are in WHERE or other odd places. Another possible answer is to just throw a "not implemented" error; but that doesn't seem terribly helpful, and I think it wouldn't save a lot of code anyway. Thoughts? regards, tom lane
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Andres Freund <andres@2ndquadrant.com> — 2014-06-14T19:45:08Z
Hi, On 2014-06-14 15:35:33 -0400, Tom Lane wrote: > Given that ON UPDATE rules are close to being a deprecated feature, > it doesn't seem appropriate to work harder than this; and frankly > I don't see how we could avoid multiple sub-select evaluations anyway, > if the NEW references are in WHERE or other odd places. > > Another possible answer is to just throw a "not implemented" error; > but that doesn't seem terribly helpful, and I think it wouldn't save > a lot of code anyway. I vote for throwing an error. This would make the rules about how rules can be used safely even more confusing. I don't think anybody would be helped by that. If somebody wrote a halfway sane ON UPDATE rule (i.e. calling a function to do the dirty work) it wouldn't be sane anymore if somebody starts to use the new syntax... Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Tom Lane <tgl@sss.pgh.pa.us> — 2014-06-14T19:48:52Z
Andres Freund <andres@2ndquadrant.com> writes: > Hi, > On 2014-06-14 15:35:33 -0400, Tom Lane wrote: >> Given that ON UPDATE rules are close to being a deprecated feature, >> it doesn't seem appropriate to work harder than this; and frankly >> I don't see how we could avoid multiple sub-select evaluations anyway, >> if the NEW references are in WHERE or other odd places. >> >> Another possible answer is to just throw a "not implemented" error; >> but that doesn't seem terribly helpful, and I think it wouldn't save >> a lot of code anyway. > I vote for throwing an error. This would make the rules about how rules > can be used safely even more confusing. I don't think anybody would be > helped by that. If somebody wrote a halfway sane ON UPDATE rule > (i.e. calling a function to do the dirty work) it wouldn't be sane > anymore if somebody starts to use the new syntax... Well, it wouldn't be "unsafe" (barring volatile functions in the UPDATE, which are unsafe already). It might be slow, but that's probably better than failing. regards, tom lane
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Andres Freund <andres@2ndquadrant.com> — 2014-06-14T19:52:30Z
On 2014-06-14 15:48:52 -0400, Tom Lane wrote: > Andres Freund <andres@2ndquadrant.com> writes: > > Hi, > > On 2014-06-14 15:35:33 -0400, Tom Lane wrote: > >> Given that ON UPDATE rules are close to being a deprecated feature, > >> it doesn't seem appropriate to work harder than this; and frankly > >> I don't see how we could avoid multiple sub-select evaluations anyway, > >> if the NEW references are in WHERE or other odd places. > >> > >> Another possible answer is to just throw a "not implemented" error; > >> but that doesn't seem terribly helpful, and I think it wouldn't save > >> a lot of code anyway. > > > I vote for throwing an error. This would make the rules about how rules > > can be used safely even more confusing. I don't think anybody would be > > helped by that. If somebody wrote a halfway sane ON UPDATE rule > > (i.e. calling a function to do the dirty work) it wouldn't be sane > > anymore if somebody starts to use the new syntax... > > Well, it wouldn't be "unsafe" (barring volatile functions in the UPDATE, > which are unsafe already). It might be slow, but that's probably better > than failing. I forgot the details, but IIRC it's possible to write a ON UPDATE ... DO INSTEAD rule that's safe wrt multiple evaluations today by calling a function passing in the old pkey and NEW. At least I believed so at some point in the past :P Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Tom Lane <tgl@sss.pgh.pa.us> — 2014-06-14T20:44:10Z
Andres Freund <andres@2ndquadrant.com> writes: > On 2014-06-14 15:48:52 -0400, Tom Lane wrote: >> Well, it wouldn't be "unsafe" (barring volatile functions in the UPDATE, >> which are unsafe already). It might be slow, but that's probably better >> than failing. > I forgot the details, but IIRC it's possible to write a ON UPDATE ... > DO INSTEAD rule that's safe wrt multiple evaluations today by calling a > function passing in the old pkey and NEW. At least I believed so at some > point in the past :P Hm. But you might as well use a trigger, no? Is anyone likely to actually be doing such a thing? It's conceivable that we could optimize the special case of NEW.*, especially if it appears in the rule query's targetlist. But it's trouble I don't really care to undertake ... regards, tom lane
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Andres Freund <andres@2ndquadrant.com> — 2014-06-14T20:51:58Z
On 2014-06-14 16:44:10 -0400, Tom Lane wrote: > Andres Freund <andres@2ndquadrant.com> writes: > > On 2014-06-14 15:48:52 -0400, Tom Lane wrote: > >> Well, it wouldn't be "unsafe" (barring volatile functions in the UPDATE, > >> which are unsafe already). It might be slow, but that's probably better > >> than failing. > > > I forgot the details, but IIRC it's possible to write a ON UPDATE ... > > DO INSTEAD rule that's safe wrt multiple evaluations today by calling a > > function passing in the old pkey and NEW. At least I believed so at some > > point in the past :P > > Hm. But you might as well use a trigger, no? Is anyone likely to > actually be doing such a thing? I don't think anybody is likely to do such a thing on an actual table, but INSTEAD OF for views is pretty new. For a long time rules were the the only way to implement updatable views (including any form of row level security). > It's conceivable that we could optimize the special case of NEW.*, > especially if it appears in the rule query's targetlist. But it's > trouble I don't really care to undertake ... I think it's fine to just throw an error. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Jim C. Nasby <jim@nasby.net> — 2014-06-15T00:27:03Z
On 6/14/14, 3:51 PM, Andres Freund wrote: >> Hm. But you might as well use a trigger, no? Is anyone likely to >> >actually be doing such a thing? > I don't think anybody is likely to do such a thing on an actual table, > but INSTEAD OF for views is pretty new. For a long time rules were the > the only way to implement updatable views (including any form of row > level security). > >> >It's conceivable that we could optimize the special case of NEW.*, >> >especially if it appears in the rule query's targetlist. But it's >> >trouble I don't really care to undertake ... > I think it's fine to just throw an error. If there was a showstopper to moving forward with rule support I think it'd be OK to throw our hands in the air, but that's not the case here. I'm in favor of doing the substitution, just like we do today with RULES, warts and all. We already warn people against using rules and that they're very difficult to get correct, so I don't think double eval of an expression should surprise anyone. -- Jim C. Nasby, Data Architect jim@nasby.net 512.569.9461 (cell) http://jim.nasby.net
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Andres Freund <andres@2ndquadrant.com> — 2014-06-15T00:39:27Z
On 2014-06-14 19:27:03 -0500, Jim Nasby wrote: > On 6/14/14, 3:51 PM, Andres Freund wrote: > >>Hm. But you might as well use a trigger, no? Is anyone likely to > >>>actually be doing such a thing? > >I don't think anybody is likely to do such a thing on an actual table, > >but INSTEAD OF for views is pretty new. For a long time rules were the > >the only way to implement updatable views (including any form of row > >level security). > > > >>>It's conceivable that we could optimize the special case of NEW.*, > >>>especially if it appears in the rule query's targetlist. But it's > >>>trouble I don't really care to undertake ... > >I think it's fine to just throw an error. > > If there was a showstopper to moving forward with rule support I think > it'd be OK to throw our hands in the air, but that's not the case > here. > > I'm in favor of doing the substitution, just like we do today with > RULES, warts and all. We already warn people against using rules and > that they're very difficult to get correct, so I don't think double > eval of an expression should surprise anyone. It makes a formerly correct/safe rule unsafe. That's a showstopper from my POV. There's *STILL* no proper warning against rules in the manual, btw. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Martijn van Oosterhout <kleptog@svana.org> — 2014-06-17T07:18:18Z
On Sat, Jun 14, 2014 at 03:35:33PM -0400, Tom Lane wrote: > The best that I think is reasonable to do in such cases is to pull out > a separate copy of the sub-select for each actual NEW reference in a > rule query. So the example above would give rise to an expanded > rule query along the lines of > > INSERT INTO foolog VALUES ( (SELECT x as a, y as b, ...).a, > (SELECT x as a, y as b, ...).b, > ... ); Would it not be possible to use WITH here, like: WITH bar AS ( ... subselect ... ) INSERT INTO foolog VALUES (bar.a, bar.b, ...) Or am I missing something? Have a nice day, -- Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/ > He who writes carelessly confesses thereby at the very outset that he does > not attach much importance to his own thoughts. -- Arthur Schopenhauer
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Hannu Krosing <hannu@2ndquadrant.com> — 2014-06-17T07:43:14Z
On 06/14/2014 09:35 PM, Tom Lane wrote: > As I mentioned awhile ago, I'm thinking about implementing the > SQL-standard construct > > UPDATE foo SET ..., (a,b,...) = (SELECT x,y,...), ... > > I've run into a rather nasty problem, which is how does this interact > with expansion of NEW references in ON UPDATE rules? Was'nt there a plan (consensus?) about deprecating rules altogether ? Cheers Hannu > For example, > suppose foo has a rule > > ON UPDATE DO ALSO INSERT INTO foolog VALUES (new.a, new.b, ...); > > The existing implementation relies on being able to pull expressions > for individual fields' new values out of the UPDATE targetlist; but > there is no independent expression for the new value of "a" here. > Worse yet, the NEW references might be in WHERE quals, or some other > place outside the targetlist of the rule query, which pretty much > breaks the implementation I'd sketched earlier. > > The best that I think is reasonable to do in such cases is to pull out > a separate copy of the sub-select for each actual NEW reference in a > rule query. So the example above would give rise to an expanded > rule query along the lines of > > INSERT INTO foolog VALUES ( (SELECT x as a, y as b, ...).a, > (SELECT x as a, y as b, ...).b, > ... ); > > which would work, but it would re-evaluate the sub-select more times > than the user might be hoping. (Of course, if there are volatile > functions in the sub-select, he's screwed, but that's not a new > problem with rules.) > > Given that ON UPDATE rules are close to being a deprecated feature, > it doesn't seem appropriate to work harder than this; and frankly > I don't see how we could avoid multiple sub-select evaluations anyway, > if the NEW references are in WHERE or other odd places. > > Another possible answer is to just throw a "not implemented" error; > but that doesn't seem terribly helpful, and I think it wouldn't save > a lot of code anyway. > > Thoughts? > > regards, tom lane > > -- Hannu Krosing PostgreSQL Consultant Performance, Scalability and High Availability 2ndQuadrant Nordic OÜ
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Vik Fearing <vik.fearing@dalibo.com> — 2014-06-17T09:22:17Z
On 06/17/2014 09:43 AM, Hannu Krosing wrote: > On 06/14/2014 09:35 PM, Tom Lane wrote: >> > As I mentioned awhile ago, I'm thinking about implementing the >> > SQL-standard construct >> > >> > UPDATE foo SET ..., (a,b,...) = (SELECT x,y,...), ... >> > >> > I've run into a rather nasty problem, which is how does this interact >> > with expansion of NEW references in ON UPDATE rules? > > Was'nt there a plan (consensus?) about deprecating rules altogether ? I believe that was just for user access to them, ie CREATE RULE. I don't think there was ever question of purging them from the code base. -- Vik
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Hannu Krosing <hannu@2ndquadrant.com> — 2014-06-17T12:38:40Z
On 06/17/2014 11:22 AM, Vik Fearing wrote: > On 06/17/2014 09:43 AM, Hannu Krosing wrote: >> On 06/14/2014 09:35 PM, Tom Lane wrote: >>>> As I mentioned awhile ago, I'm thinking about implementing the >>>> SQL-standard construct >>>> >>>> UPDATE foo SET ..., (a,b,...) = (SELECT x,y,...), ... >>>> >>>> I've run into a rather nasty problem, which is how does this interact >>>> with expansion of NEW references in ON UPDATE rules? >> Was'nt there a plan (consensus?) about deprecating rules altogether ? > I believe that was just for user access to them, ie CREATE RULE. I > don't think there was ever question of purging them from the code base. But are there any cases, where UPDATE rules are created behind the scenes ? -- Hannu Krosing PostgreSQL Consultant Performance, Scalability and High Availability 2ndQuadrant Nordic OÜ
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Andres Freund <andres@2ndquadrant.com> — 2014-06-17T12:47:41Z
On 2014-06-17 11:22:17 +0200, Vik Fearing wrote: > On 06/17/2014 09:43 AM, Hannu Krosing wrote: > > On 06/14/2014 09:35 PM, Tom Lane wrote: > >> > As I mentioned awhile ago, I'm thinking about implementing the > >> > SQL-standard construct > >> > > >> > UPDATE foo SET ..., (a,b,...) = (SELECT x,y,...), ... > >> > > >> > I've run into a rather nasty problem, which is how does this interact > >> > with expansion of NEW references in ON UPDATE rules? > > > > Was'nt there a plan (consensus?) about deprecating rules altogether ? > > I believe that was just for user access to them, ie CREATE RULE. I > don't think there was ever question of purging them from the code base. I don't think any such concensus has been made? I wish it were, but the last discussions about it imo ended quite differently. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Tom Lane <tgl@sss.pgh.pa.us> — 2014-06-17T13:46:13Z
Andres Freund <andres@2ndquadrant.com> writes: > On 2014-06-17 11:22:17 +0200, Vik Fearing wrote: >> On 06/17/2014 09:43 AM, Hannu Krosing wrote: >>> Was'nt there a plan (consensus?) about deprecating rules altogether ? >> I believe that was just for user access to them, ie CREATE RULE. I >> don't think there was ever question of purging them from the code base. > I don't think any such concensus has been made? I wish it were, but the > last discussions about it imo ended quite differently. Yeah, I don't think there's any prospect of removing them in the near future. We'd need a (better-designed) replacement feature first. regards, tom lane
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Andres Freund <andres@2ndquadrant.com> — 2014-06-17T13:48:05Z
On 2014-06-17 09:46:13 -0400, Tom Lane wrote: > Andres Freund <andres@2ndquadrant.com> writes: > > On 2014-06-17 11:22:17 +0200, Vik Fearing wrote: > >> On 06/17/2014 09:43 AM, Hannu Krosing wrote: > >>> Was'nt there a plan (consensus?) about deprecating rules altogether ? > > >> I believe that was just for user access to them, ie CREATE RULE. I > >> don't think there was ever question of purging them from the code base. > > > I don't think any such concensus has been made? I wish it were, but the > > last discussions about it imo ended quite differently. > > Yeah, I don't think there's any prospect of removing them in the near > future. We'd need a (better-designed) replacement feature first. IMO INSTEAD triggers pretty much are that. We only need to make them work for normal relations as well (partitioning!) and we're pretty much there. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Tom Lane <tgl@sss.pgh.pa.us> — 2014-06-17T14:02:51Z
Martijn van Oosterhout <kleptog@svana.org> writes: > Would it not be possible to use WITH here, like: > WITH bar AS ( ... subselect ... ) > INSERT INTO foolog VALUES (bar.a, bar.b, ...) Don't think it works if the sub-select is correlated. Consider something like UPDATE summary_table s SET (sumx, sumy) = (SELECT sum(x), sum(y) FROM detail_table d WHERE d.group = s.group) and suppose we have a logging rule like the above on summary_table. You can't push the sub-select into a WITH because it depends on s.group. With sufficient intelligence you could rewrite the query entirely, I guess, but no simple transformation is going to cope. But come to think of it, WITH is already an interesting precedent: if you look into rewriteHandler.c you'll notice a boatload of corner cases where the rewriter just throws up its hands for various combinations of rules and statements containing WITH. So maybe that lends a bit more weight to Andres' position that it's okay to consider this an unimplemented feature. regards, tom lane -
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Merlin Moncure <mmoncure@gmail.com> — 2014-06-17T14:31:00Z
On Tue, Jun 17, 2014 at 9:02 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > But come to think of it, WITH is already an interesting precedent: if you > look into rewriteHandler.c you'll notice a boatload of corner cases where > the rewriter just throws up its hands for various combinations of rules > and statements containing WITH. So maybe that lends a bit more weight > to Andres' position that it's okay to consider this an unimplemented > feature. This reflects previous consensus AIUI. RULES came up in similar way with the 'data modifying with' feature; it was decided that as long as old stuff didn't break new features don't necessarily have to go through the motions. This essentially deprecates rules IMO, which is fine. Maybe a small adjustment of the note in the rule documentation couldn't hurt; it currently warns based on performance...a heads up that current and future SQL features might not be fully supported would be nice. merlin
-
Re: UPDATE SET (a,b,c) = (SELECT ...) versus rules
Tom Lane <tgl@sss.pgh.pa.us> — 2014-06-17T23:09:12Z
Andres Freund <andres@2ndquadrant.com> writes: > On 2014-06-14 19:27:03 -0500, Jim Nasby wrote: >> I'm in favor of doing the substitution, just like we do today with >> RULES, warts and all. We already warn people against using rules and >> that they're very difficult to get correct, so I don't think double >> eval of an expression should surprise anyone. > It makes a formerly correct/safe rule unsafe. That's a showstopper from > my POV. Andres' objection has some merit, and it doesn't seem like very many people are concerned about throwing errors for new constructs if it's hard to make them work with rules. So I've updated the patch to throw an error for now. We can always revisit it later if someone has a good idea about how to implement it. > There's *STILL* no proper warning against rules in the manual, btw. Not sure what you want for a "proper warning", but I put in a <caution> that I think mentions the known gotchas. This patch is now complete as far as I'm concerned. If there are not objections I'll be committing it before long. regards, tom lane