Thread: "CREATE RULE ... ON SELECT": redundant?

"CREATE RULE ... ON SELECT": redundant?

From
Ian Lawrence Barwick
Date:
Hi

Commit b23cd185f [1] forbids manual creation of ON SELECT rule on
a table, and updated the main rules documentation [2], but didn't update
the corresponding CREATE RULE page [3].

[1] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b23cd185fd5410e5204683933f848d4583e34b35
[2] https://www.postgresql.org/docs/devel/rules-views.html
[3] https://www.postgresql.org/docs/devel/sql-createrule.html

While poking around at an update for that, unless I'm missing something it is
now not possible to use "CREATE RULE ... ON SELECT" for any kind of relation,
given that it's disallowed on views / material views already.

Assuming that's the case, that makes this useless syntax in a non-SQL-standard
command, is there any reason to keep it in the grammar at all?

Attached suggested patch removes it entirely and updates the CREATE RULE
documentation.

Apart from removing ON SELECT from the grammar, the main change is the removal
of usage checks in DefineQueryRewrite(), as the only time it is called with the
event_type set to "CMD_SELECT" is when a view/matview is created, and presumably
we can trust the internal caller to do the right thing. I added an Assert in
just in case, dunno if that's really needed. In passing, a redundant workaround
for pre-7.3 rule names gets removed as well.

I note that with or without this change, pg_get_ruledef() e.g. executed with:

  SELECT pg_get_ruledef(oid) FROM pg_rewrite WHERE
ev_class='some_view'::regclass;

emits SQL for CREATE RULE which can no longer be executed; I don't think there
is anything which can be done about that other than noting it as a historical
implementation oddity.


Regards

Ian Barwick

Attachment

Re: "CREATE RULE ... ON SELECT": redundant?

From
Tom Lane
Date:
Ian Lawrence Barwick <barwick@gmail.com> writes:
> While poking around at an update for that, unless I'm missing something it is
> now not possible to use "CREATE RULE ... ON SELECT" for any kind of relation,
> given that it's disallowed on views / material views already.

What makes you think it's disallowed on views?  You do need to use
CREATE OR REPLACE, since the rule will already exist.

regression=# create view v as select * from int8_tbl ;
CREATE VIEW
regression=# create or replace rule "_RETURN" as on select to v do instead select q1, q2+1 as q2 from int8_tbl ;
CREATE RULE
regression=# \d+ v
                             View "public.v"
 Column |  Type  | Collation | Nullable | Default | Storage | Description
--------+--------+-----------+----------+---------+---------+-------------
 q1     | bigint |           |          |         | plain   |
 q2     | bigint |           |          |         | plain   |
View definition:
 SELECT int8_tbl.q1,
    int8_tbl.q2 + 1 AS q2
   FROM int8_tbl;

Now, this is certainly syntax that's deprecated in favor of using
CREATE OR REPLACE VIEW, but I'm very hesitant to remove it.  ISTR
that ancient pg_dump files used it in cases involving circular
dependencies.  If you want to adjust the docs to say that it's
deprecated in favor of CREATE OR REPLACE VIEW, I could get on
board with that.

            regards, tom lane



Re: "CREATE RULE ... ON SELECT": redundant?

From
Ian Lawrence Barwick
Date:
2023年5月4日(木) 12:51 Tom Lane <tgl@sss.pgh.pa.us>:
>
> Ian Lawrence Barwick <barwick@gmail.com> writes:
> > While poking around at an update for that, unless I'm missing something it is
> > now not possible to use "CREATE RULE ... ON SELECT" for any kind of relation,
> > given that it's disallowed on views / material views already.
>
> What makes you think it's disallowed on views?  You do need to use
> CREATE OR REPLACE, since the rule will already exist.

Ah, "OR REPLACE". Knew I was missing something.

> regression=# create view v as select * from int8_tbl ;
> CREATE VIEW
> regression=# create or replace rule "_RETURN" as on select to v do instead select q1, q2+1 as q2 from int8_tbl ;
> CREATE RULE
> regression=# \d+ v
>                              View "public.v"
>  Column |  Type  | Collation | Nullable | Default | Storage | Description
> --------+--------+-----------+----------+---------+---------+-------------
>  q1     | bigint |           |          |         | plain   |
>  q2     | bigint |           |          |         | plain   |
> View definition:
>  SELECT int8_tbl.q1,
>     int8_tbl.q2 + 1 AS q2
>    FROM int8_tbl;
>
> Now, this is certainly syntax that's deprecated in favor of using
> CREATE OR REPLACE VIEW, but I'm very hesitant to remove it.  ISTR
> that ancient pg_dump files used it in cases involving circular
> dependencies.  If you want to adjust the docs to say that it's
> deprecated in favor of CREATE OR REPLACE VIEW, I could get on
> board with that.

'k, I will work on a doc patch.

Thanks

Ian Barwick



Re: "CREATE RULE ... ON SELECT": redundant?

From
Andrew Gierth
Date:
>>>>> "Tom" == Tom Lane <tgl@sss.pgh.pa.us> writes:

 Tom> Now, this is certainly syntax that's deprecated in favor of using
 Tom> CREATE OR REPLACE VIEW, but I'm very hesitant to remove it. ISTR
 Tom> that ancient pg_dump files used it in cases involving circular
 Tom> dependencies.

I thought they used CREATE RULE on a table?

In fact here is an example from a pg 9.5 pg_dump output (with cruft
removed):

CREATE TABLE public.cdep (
    a integer,
    b text
);
CREATE FUNCTION public.cdep_impl() RETURNS SETOF public.cdep
    LANGUAGE plpgsql
    AS $$ begin return query select a,b from (values (1,'foo'),(2,'bar')) v(a,b); end; $$;
CREATE RULE "_RETURN" AS
    ON SELECT TO public.cdep DO INSTEAD  SELECT cdep_impl.a,
    cdep_impl.b
   FROM public.cdep_impl() cdep_impl(a, b);

and this now fails to restore:

psql:t1.sql:68: ERROR:  relation "cdep" cannot have ON SELECT rules
DETAIL:  This operation is not supported for tables.

-- 
Andrew (irc:RhodiumToad)



Re: "CREATE RULE ... ON SELECT": redundant?

From
Andrew Gierth
Date:
>>>>> "Andrew" == Andrew Gierth <andrew@tao11.riddles.org.uk> writes:

 Andrew> I thought they used CREATE RULE on a table?

 Andrew> In fact here is an example from a pg 9.5 pg_dump output (with
 Andrew> cruft removed):

And checking other versions, 9.6 is the same, it's only with pg 10 that
it switches to creating a dummy view instead of a table (and using
CREATE OR REPLACE VIEW, no mention of rules).

So if the goal was to preserve compatibility with pre-pg10 dumps, that's
already broken; if that's ok, then I don't see any obvious reason not to
also remove or at least deprecate CREATE RULE ... ON SELECT for views.

-- 
Andrew (irc:RhodiumToad)



Re: "CREATE RULE ... ON SELECT": redundant?

From
Tom Lane
Date:
Andrew Gierth <andrew@tao11.riddles.org.uk> writes:
> And checking other versions, 9.6 is the same, it's only with pg 10 that
> it switches to creating a dummy view instead of a table (and using
> CREATE OR REPLACE VIEW, no mention of rules).

9.6.16 or later will use CREATE OR REPLACE VIEW, cf 404cbc562.

> So if the goal was to preserve compatibility with pre-pg10 dumps, that's
> already broken; if that's ok, then I don't see any obvious reason not to
> also remove or at least deprecate CREATE RULE ... ON SELECT for views.

Since the CREATE OR REPLACE case still works, I don't think removing
it is OK.

            regards, tom lane