}
}
+ /*
+ * Similarly, make sure the FOR PORTION OF column is updateable. This is
+ * not included in the columns tested above, and we have to test it even
+ * for DELETEs.
+ */
+ if (parsetree->forPortionOf)
+ {
+ AttrNumber rangeAttno;
+ Bitmapset *fpo_cols;
+ char *non_updatable_col;
+ const char *fpo_update_detail;
+
+ rangeAttno = parsetree->forPortionOf->rangeVar->varattno;
+ fpo_cols = bms_make_singleton(rangeAttno - FirstLowInvalidHeapAttributeNumber);
+
+ fpo_update_detail = view_cols_are_auto_updatable(viewquery,
+ fpo_cols,
+ NULL,
+ &non_updatable_col);
+ if (fpo_update_detail)
+ {
+ switch (parsetree->commandType)
+ {
+ case CMD_UPDATE:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot update column \"%s\" of view \"%s\"",
+ non_updatable_col,
+ RelationGetRelationName(view)),
+ errdetail_internal("%s", _(fpo_update_detail))));
+ break;
+ case CMD_DELETE:
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot delete from view \"%s\" using FOR PORTION OF \"%s\"",
+ RelationGetRelationName(view),
+ non_updatable_col),
+ errdetail_internal("%s", _(fpo_update_detail))));
+ break;
+ default:
+ elog(ERROR, "unrecognized CmdType: %d",
+ (int) parsetree->commandType);
+ break;
+ }
+ }
+ }
+
/*
* For MERGE, there must not be any INSTEAD OF triggers on an otherwise
* updatable view. The caller already checked that there isn't a full set
0 | 1 | ["Sat Jan 01 00:00:00 2022","Tue Jan 01 00:00:00 2030") | [1,2) | 2.0
(3 rows)
+-- UPDATE/DELETE FOR PORTION fails if the column is not updatable
+-- (e.g. a computed expression, not a base column):
+create view uv_fpo_view_nonupd as
+ select id, '[1,20]'::int4range as valid_at, b
+ from uv_fpo_tab;
+-- Updating fails:
+update uv_fpo_view_nonupd for portion of valid_at from 1 to 10 set b = 2;
+ERROR: cannot update column "valid_at" of view "uv_fpo_view_nonupd"
+DETAIL: View columns that are not columns of their base relation are not updatable.
+-- Deleting fails:
+delete from uv_fpo_view_nonupd for portion of valid_at from 1 to 10;
+ERROR: cannot delete from view "uv_fpo_view_nonupd" using FOR PORTION OF "valid_at"
+DETAIL: View columns that are not columns of their base relation are not updatable.
+drop view uv_fpo_view_nonupd;
-- Test whole-row references to the view
create table uv_iocu_tab (a int unique, b text);
create view uv_iocu_view as
delete from uv_fpo_view for portion of valid_at from '2017-01-01' to '2022-01-01' where id = '[1,1]';
select * from uv_fpo_view order by id, valid_at;
+-- UPDATE/DELETE FOR PORTION fails if the column is not updatable
+-- (e.g. a computed expression, not a base column):
+create view uv_fpo_view_nonupd as
+ select id, '[1,20]'::int4range as valid_at, b
+ from uv_fpo_tab;
+-- Updating fails:
+update uv_fpo_view_nonupd for portion of valid_at from 1 to 10 set b = 2;
+-- Deleting fails:
+delete from uv_fpo_view_nonupd for portion of valid_at from 1 to 10;
+drop view uv_fpo_view_nonupd;
+
-- Test whole-row references to the view
create table uv_iocu_tab (a int unique, b text);
create view uv_iocu_view as