Hi,

On 2026-09-03 09:08:10 -0700, Paul A Jungwirth wrote:
> On Wed, Sep 2, 2026 at 9:20 PM Ewan Young <[email protected]> wrote:
> >
> > An UPDATE/DELETE ... FOR PORTION OF against a view that has an
> > unqualified DO INSTEAD rule silently ignores the FOR PORTION OF clause
> > and modifies (or deletes) the whole temporal row instead of just the
> > requested portion -- no error, no warning:
> >
> >   CREATE TABLE t (id int, valid_at daterange, name text);
> >   INSERT INTO t VALUES (1, '[2020-01-01,2021-01-01)', 'a');
> >   CREATE VIEW v AS SELECT * FROM t;
> >   CREATE RULE v_upd AS ON UPDATE TO v DO INSTEAD
> >     UPDATE t SET name = NEW.name WHERE id = OLD.id;
> >
> >   UPDATE v FOR PORTION OF valid_at FROM '2020-06-01' TO '2020-07-01'
> >     SET name = 'b';
> >   SELECT * FROM t;
> >    id |        valid_at         | name
> >   ----+-------------------------+------
> >     1 | [2020-01-01,2021-01-01) | b      -- whole row changed
> >
> > The same statement on the base table (or a plain auto-updatable view)
> > correctly splits the row three ways.  DELETE is worse: DELETE ... FOR
> > PORTION OF through such a view removes the entire row.
> 
> IMO this is working as intended. If you replace the original query, we
> shouldn't skip just part of it and still execute one clause. If you
> wanted to keep the FOR PORTION OF, your rule would have said that.

That makes no sense to me. The writer of an instead-of rule can't
control/predict whether the user uses FOR PORTION OF? How could one possibly
write such a rule that works both when FOR PORTION OF is used and when not?

I think rules, except for being an implementation detail of views, are a crazy
feature that should have been removed long ago, but I don't think that really
makes the behaviour here defensible.

Greetings,

Andres Freund


Reply via email to