From dc3eb5638349e74a6628130a5101ce866455f4a3 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 12 Jun 2013 17:52:54 -0400 Subject: Improve updatability checking for views and foreign tables. Extend the FDW API (which we already changed for 9.3) so that an FDW can report whether specific foreign tables are insertable/updatable/deletable. The default assumption continues to be that they're updatable if the relevant executor callback function is supplied by the FDW, but finer granularity is now possible. As a test case, add an "updatable" option to contrib/postgres_fdw. This patch also fixes the information_schema views, which previously did not think that foreign tables were ever updatable, and fixes view_is_auto_updatable() so that a view on a foreign table can be auto-updatable. initdb forced due to changes in information_schema views and the functions they rely on. This is a bit unfortunate to do post-beta1, but if we don't change this now then we'll have another API break for FDWs when we do change it. Dean Rasheed, somewhat editorialized on by Tom Lane --- src/backend/utils/adt/misc.c | 51 ++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'src/backend/utils/adt/misc.c') diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 829ce59888..bf06ec048f 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -528,30 +528,49 @@ pg_collation_for(PG_FUNCTION_ARGS) /* - * information_schema support functions + * pg_relation_is_updatable - determine which update events the specified + * relation supports. * - * Test whether a view (identified by pg_class OID) is insertable-into or - * updatable. The latter requires delete capability too. This is an - * artifact of the way the SQL standard defines the information_schema views: - * if we defined separate functions for update and delete, we'd double the - * work required to compute the view columns. - * - * These rely on relation_is_updatable(), which is in rewriteHandler.c. + * This relies on relation_is_updatable() in rewriteHandler.c, which see + * for additional information. */ Datum -pg_view_is_insertable(PG_FUNCTION_ARGS) +pg_relation_is_updatable(PG_FUNCTION_ARGS) { - Oid viewoid = PG_GETARG_OID(0); - int req_events = (1 << CMD_INSERT); + Oid reloid = PG_GETARG_OID(0); + bool include_triggers = PG_GETARG_BOOL(1); - PG_RETURN_BOOL(relation_is_updatable(viewoid, req_events)); + PG_RETURN_INT32(relation_is_updatable(reloid, include_triggers)); } +/* + * pg_column_is_updatable - determine whether a column is updatable + * + * Currently we just check whether the column's relation is updatable. + * Eventually we might allow views to have some updatable and some + * non-updatable columns. + * + * Also, this function encapsulates the decision about just what + * information_schema.columns.is_updatable actually means. It's not clear + * whether deletability of the column's relation should be required, so + * we want that decision in C code where we could change it without initdb. + */ Datum -pg_view_is_updatable(PG_FUNCTION_ARGS) +pg_column_is_updatable(PG_FUNCTION_ARGS) { - Oid viewoid = PG_GETARG_OID(0); - int req_events = (1 << CMD_UPDATE) | (1 << CMD_DELETE); + Oid reloid = PG_GETARG_OID(0); + AttrNumber attnum = PG_GETARG_INT16(1); + bool include_triggers = PG_GETARG_BOOL(2); + int events; + + /* System columns are never updatable */ + if (attnum <= 0) + PG_RETURN_BOOL(false); + + events = relation_is_updatable(reloid, include_triggers); + + /* We require both updatability and deletability of the relation */ +#define REQ_EVENTS ((1 << CMD_UPDATE) | (1 << CMD_DELETE)) - PG_RETURN_BOOL(relation_is_updatable(viewoid, req_events)); + PG_RETURN_BOOL((events & REQ_EVENTS) == REQ_EVENTS); } -- cgit v1.2.1