Place all views in a shared schema

This commit is contained in:
Raúl Marín
2019-11-14 18:45:09 +01:00
parent 6e455efcdd
commit e69d3b1c30
4 changed files with 57 additions and 46 deletions

View File

@@ -5,9 +5,16 @@
--
-- This function is just a placement to store and use the pattern for
-- foreign object names
-- Servers: cdb_fs_$(server_name)
-- Schemas: cdb_fs_schema_$(md5sum(server_name || remote_schema_name))
-- Owner role: cdb_fs_$(md5sum(current_database() || server_name)
-- Servers: cdb_fs_$(server_name)
-- View schema: cdb_fs_$(server_name)
-- > This is where all views created when importing tables are placed
-- > One server has only one view schema
-- Import Schemas: cdb_fs_schema_$(md5sum(server_name || remote_schema_name))
-- > This is where the foreign tables are placed
-- > One server has one import schema per remote schema plus auxiliar ones used
-- to access the remote catalog (pg_catalog, information_schema...)
-- Owner role: cdb_fs_$(md5sum(current_database() || server_name)
-- > This is the role than owns all schemas and tables related to the server
--
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Name_Pattern()
RETURNS TEXT
@@ -19,6 +26,7 @@ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
--
-- Produce a valid DB name for servers generated for the Federated Server
-- If check_existence is true, it'll throw if the server doesn't exists
-- This name is also used to
--
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Generate_Server_Name(input_name TEXT, check_existence BOOL)
RETURNS NAME

View File

@@ -173,6 +173,8 @@ LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
-- can be used through SQL and Maps API's.
-- If the table was already exported, it will be dropped and re-imported
--
-- The view is placed under the server's view schema (cdb_fs_$(server_name))
--
-- E.g:
-- SELECT cartodb.CDB_SetUp_PG_Federated_Table(
-- 'amazon', -- mandatory, name of the federated server
@@ -198,7 +200,10 @@ AS $$
DECLARE
server_internal name := @extschema@.__CDB_FS_Generate_Server_Name(input_name => server, check_existence => false);
local_schema name := @extschema@.__CDB_FS_Create_Schema(server_internal, remote_schema);
src_table REGCLASS;
role_name name := @extschema@.__CDB_FS_Generate_Server_Role_Name(server_internal);
src_table REGCLASS; -- import_schema.remote_table - import_schema is local_schema
local_view text; -- view_schema.local_name - view_schema is server_internal
rest_of_cols TEXT[];
geom_expression TEXT;
@@ -284,36 +289,28 @@ BEGIN
webmercator_expression
];
-- To create the view we switch to the caller role to make sure we have permissions
-- to write in the destination schema
RESET ROLE;
-- Create view schema if it doesn't exist
IF NOT EXISTS (SELECT oid FROM pg_namespace WHERE nspname = server_internal) THEN
EXECUTE 'CREATE SCHEMA ' || quote_ident(server_internal) || ' AUTHORIZATION ' || quote_ident(role_name);
END IF;
-- Create a view with homogeneous CDB fields
BEGIN
EXECUTE format(
'CREATE OR REPLACE VIEW %1$I AS
SELECT %2s
FROM %3$s t',
local_name,
'CREATE OR REPLACE VIEW %1$I.%2$I AS
SELECT %3s
FROM %4$s t',
server_internal, local_name,
array_to_string(carto_columns_expression || rest_of_cols, ','),
src_table
);
EXCEPTION WHEN OTHERS THEN
IF EXISTS (SELECT to_regclass(local_name)) THEN
RAISE EXCEPTION 'Could not import table "%" as "%" already exists: %', remote_table, local_name, SQLERRM;
IF EXISTS (SELECT to_regclass(format('%1$I.%2$I', server_internal, local_name))) THEN
RAISE EXCEPTION 'Could not import table "%" as "%.%" already exists', remote_table, server_internal, local_name;
ELSE
RAISE EXCEPTION 'Could not import table "%" as "%": %', remote_table, local_name, SQLERRM;
END IF;
END;
BEGIN
EXECUTE format('ALTER VIEW %1$I OWNER TO %I',
local_name,
cartodb.__CDB_FS_Generate_Server_Role_Name(server_internal));
EXCEPTION WHEN OTHERS THEN
RAISE WARNING 'View "%" could not be shared with other users: %. Execute "ALTER VIEW %1$I OWNER TO %I" to share it',
local_name, SQLERRM, local_name, cartodb.__CDB_FS_Generate_Server_Role_Name(server_internal);
END;
END
$$
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;