Merge pull request #383 from CartoDB/federated_diagnostics
Retrieve target PG and postgis versions
This commit is contained in:
@@ -0,0 +1,145 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Private functions
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Import a foreign table if it does not exist
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Import_If_Not_Exists(server_internal name, remote_schema name, remote_table name)
|
||||||
|
RETURNS void
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
local_schema name := @extschema@.__CDB_FS_Create_Schema(server_internal, remote_schema);
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT * FROM pg_class
|
||||||
|
WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = local_schema)
|
||||||
|
AND relname = remote_table
|
||||||
|
) THEN
|
||||||
|
EXECUTE format('IMPORT FOREIGN SCHEMA %I LIMIT TO (%I) FROM SERVER %I INTO %I',
|
||||||
|
remote_schema, remote_table, server_internal, local_schema);
|
||||||
|
END IF;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Get the version of a remote PG server
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Foreign_Server_Version_PG(server_internal name)
|
||||||
|
RETURNS text
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
remote_schema name := 'pg_catalog';
|
||||||
|
remote_table name := 'pg_settings';
|
||||||
|
local_schema name := @extschema@.__CDB_FS_Create_Schema(server_internal, remote_schema);
|
||||||
|
remote_server_version text;
|
||||||
|
BEGIN
|
||||||
|
PERFORM @extschema@.__CDB_FS_Import_If_Not_Exists(server_internal, remote_schema, remote_table);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format('
|
||||||
|
SELECT setting FROM %I.%I WHERE name = ''server_version'';
|
||||||
|
', local_schema, remote_table) INTO remote_server_version;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE EXCEPTION 'Not enough permissions to access the server "%"',
|
||||||
|
@extschema@.__CDB_FS_Extract_Server_Name(server_internal);
|
||||||
|
END;
|
||||||
|
|
||||||
|
RETURN remote_server_version;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Get the PostGIS extension version of a remote PG server
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Foreign_PostGIS_Version_PG(server_internal name)
|
||||||
|
RETURNS text
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
remote_schema name := 'pg_catalog';
|
||||||
|
remote_table name := 'pg_extension';
|
||||||
|
local_schema name := @extschema@.__CDB_FS_Create_Schema(server_internal, remote_schema);
|
||||||
|
remote_postgis_version text;
|
||||||
|
BEGIN
|
||||||
|
PERFORM @extschema@.__CDB_FS_Import_If_Not_Exists(server_internal, remote_schema, remote_table);
|
||||||
|
|
||||||
|
BEGIN
|
||||||
|
EXECUTE format('
|
||||||
|
SELECT extversion FROM %I.%I WHERE extname = ''postgis'';
|
||||||
|
', local_schema, remote_table) INTO remote_postgis_version;
|
||||||
|
EXCEPTION WHEN OTHERS THEN
|
||||||
|
RAISE EXCEPTION 'Not enough permissions to access the server "%"',
|
||||||
|
@extschema@.__CDB_FS_Extract_Server_Name(server_internal);
|
||||||
|
END;
|
||||||
|
|
||||||
|
RETURN remote_postgis_version;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Get the foreign server options of a remote PG server
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Foreign_Server_Options_PG(server_internal name)
|
||||||
|
RETURNS jsonb
|
||||||
|
AS $$
|
||||||
|
-- See https://www.postgresql.org/docs/current/catalog-pg-foreign-server.html
|
||||||
|
-- See https://www.postgresql.org/docs/current/functions-info.html
|
||||||
|
SELECT jsonb_object_agg(opt.option_name, opt.option_value) FROM (
|
||||||
|
SELECT (pg_options_to_table(srvoptions)).*
|
||||||
|
FROM pg_foreign_server
|
||||||
|
WHERE srvname = server_internal
|
||||||
|
) AS opt;
|
||||||
|
$$
|
||||||
|
LANGUAGE SQL VOLATILE PARALLEL UNSAFE;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Collect and return diagnostics info from a remote PG into a jsonb
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION @extschema@.__CDB_FS_Server_Diagnostics_PG(server_internal name)
|
||||||
|
RETURNS jsonb
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
remote_server_version text := @extschema@.__CDB_FS_Foreign_Server_Version_PG(server_internal);
|
||||||
|
remote_postgis_version text := @extschema@.__CDB_FS_Foreign_PostGIS_Version_PG(server_internal);
|
||||||
|
remote_server_options jsonb := @extschema@.__CDB_FS_Foreign_Server_Options_PG(server_internal);
|
||||||
|
BEGIN
|
||||||
|
RETURN jsonb_build_object(
|
||||||
|
'server_version', remote_server_version,
|
||||||
|
'postgis_version', remote_postgis_version,
|
||||||
|
'server_options', remote_server_options
|
||||||
|
);
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Public functions
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Collect and return diagnostics info from a remote PG into a jsonb
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION @extschema@.CDB_Federated_Server_Diagnostics(server TEXT)
|
||||||
|
RETURNS jsonb
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
server_internal name := @extschema@.__CDB_FS_Generate_Server_Name(input_name => server, check_existence => true);
|
||||||
|
server_type name := @extschema@.__CDB_FS_server_type(server_internal);
|
||||||
|
BEGIN
|
||||||
|
CASE server_type
|
||||||
|
WHEN 'postgres_fdw' THEN
|
||||||
|
RETURN @extschema@.__CDB_FS_Server_Diagnostics_PG(server_internal);
|
||||||
|
ELSE
|
||||||
|
RAISE EXCEPTION 'Not implemented server type % for remote server %', server_type, server;
|
||||||
|
END CASE;
|
||||||
|
END
|
||||||
|
$$
|
||||||
|
LANGUAGE PLPGSQL VOLATILE PARALLEL UNSAFE;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../scripts-available/CDB_FederatedServerDiagnostics.sql
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
-- ===================================================================
|
||||||
|
-- create FDW objects
|
||||||
|
-- ===================================================================
|
||||||
|
\set QUIET on
|
||||||
|
SET client_min_messages TO error;
|
||||||
|
\set VERBOSITY terse
|
||||||
|
CREATE EXTENSION postgres_fdw;
|
||||||
|
|
||||||
|
CREATE ROLE cdb_fs_tester LOGIN PASSWORD 'cdb_fs_passwd';
|
||||||
|
GRANT CONNECT ON DATABASE contrib_regression TO cdb_fs_tester;
|
||||||
|
|
||||||
|
-- Create database to be used as remote
|
||||||
|
CREATE DATABASE cdb_fs_tester OWNER cdb_fs_tester;
|
||||||
|
|
||||||
|
SELECT 'C1', cartodb.CDB_Federated_Server_Register_PG(server => 'loopback'::text, config => '{
|
||||||
|
"server": {
|
||||||
|
"host": "localhost",
|
||||||
|
"port": @@PGPORT@@
|
||||||
|
},
|
||||||
|
"credentials": {
|
||||||
|
"username": "cdb_fs_tester",
|
||||||
|
"password": "cdb_fs_passwd"
|
||||||
|
}
|
||||||
|
}'::jsonb);
|
||||||
|
|
||||||
|
\c cdb_fs_tester postgres
|
||||||
|
CREATE EXTENSION postgis;
|
||||||
|
\c contrib_regression postgres
|
||||||
|
\set QUIET off
|
||||||
|
|
||||||
|
|
||||||
|
-- ===================================================================
|
||||||
|
-- Test server diagnostics function(s)
|
||||||
|
-- ===================================================================
|
||||||
|
\echo '%% It raises an error if the server does not exist'
|
||||||
|
SELECT '1.1', cartodb.CDB_Federated_Server_Diagnostics(server => 'doesNotExist');
|
||||||
|
|
||||||
|
\echo '%% It returns a jsonb object'
|
||||||
|
SELECT '1.2', pg_typeof(cartodb.CDB_Federated_Server_Diagnostics(server => 'loopback'));
|
||||||
|
|
||||||
|
\echo '%% It returns the server version'
|
||||||
|
SELECT '1.3', cartodb.CDB_Federated_Server_Diagnostics(server => 'loopback') @> format('{"server_version": "%s"}', setting)::jsonb
|
||||||
|
FROM pg_settings WHERE name = 'server_version';
|
||||||
|
|
||||||
|
\echo '%% It returns the postgis version'
|
||||||
|
SELECT '1.4', cartodb.CDB_Federated_Server_Diagnostics(server => 'loopback') @> format('{"postgis_version": "%s"}', extversion)::jsonb
|
||||||
|
FROM pg_extension WHERE extname = 'postgis';
|
||||||
|
|
||||||
|
\echo '%% It returns null as the postgis version if it is not installed'
|
||||||
|
\set QUIET on
|
||||||
|
\c cdb_fs_tester postgres
|
||||||
|
DROP EXTENSION postgis;
|
||||||
|
\c contrib_regression postgres
|
||||||
|
\set QUIET off
|
||||||
|
SELECT '1.5', cartodb.CDB_Federated_Server_Diagnostics(server => 'loopback') @> '{"postgis_version": null}'::jsonb;
|
||||||
|
|
||||||
|
\echo '%% It returns the remote server options'
|
||||||
|
SELECT '1.6', cartodb.CDB_Federated_Server_Diagnostics(server => 'loopback') @> '{"server_options": {"host": "localhost", "port": "@@PGPORT@@", "updatable": "false", "extensions": "postgis", "fetch_size": "1000", "use_remote_estimate": "true"}}'::jsonb;
|
||||||
|
|
||||||
|
|
||||||
|
-- ===================================================================
|
||||||
|
-- Cleanup
|
||||||
|
-- ===================================================================
|
||||||
|
\set QUIET on
|
||||||
|
SELECT 'D1', cartodb.CDB_Federated_Server_Unregister(server => 'loopback'::text);
|
||||||
|
-- Reconnect, using a new session in order to close FDW connections
|
||||||
|
\connect
|
||||||
|
DROP DATABASE cdb_fs_tester;
|
||||||
|
|
||||||
|
-- Drop role
|
||||||
|
REVOKE CONNECT ON DATABASE contrib_regression FROM cdb_fs_tester;
|
||||||
|
DROP ROLE cdb_fs_tester;
|
||||||
|
|
||||||
|
DROP EXTENSION postgres_fdw;
|
||||||
|
\set QUIET off
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
C1|
|
||||||
|
%% It raises an error if the server does not exist
|
||||||
|
ERROR: Server "doesNotExist" does not exist
|
||||||
|
%% It returns a jsonb object
|
||||||
|
1.2|jsonb
|
||||||
|
%% It returns the server version
|
||||||
|
1.3|t
|
||||||
|
%% It returns the postgis version
|
||||||
|
1.4|t
|
||||||
|
%% It returns null as the postgis version if it is not installed
|
||||||
|
1.5|t
|
||||||
|
%% It returns the remote server options
|
||||||
|
1.6|t
|
||||||
|
D1|
|
||||||
Reference in New Issue
Block a user