@@ -134,9 +134,9 @@ DROP TABLE t;
|
||||
-- table with single non-geometrical column
|
||||
CREATE TABLE t AS SELECT ST_SetSRID(ST_MakePoint(-1,-1),4326) as the_geom, 1::int as cartodb_id, 'this is a sentence' as description;
|
||||
SELECT CDB_CartodbfyTableCheck('t', 'check function idempotence');
|
||||
SELECT * FROM t;
|
||||
SELECT cartodb_id, the_geom, description FROM t;
|
||||
SELECT CDB_CartodbfyTableCheck('t', 'check function idempotence');
|
||||
SELECT * FROM t;
|
||||
SELECT cartodb_id, the_geom, description FROM t;
|
||||
DROP TABLE t;
|
||||
|
||||
-- table with existing srid-unconstrained (but type-constrained) the_geom
|
||||
|
||||
@@ -7,9 +7,9 @@ single non-geometrical column cartodbfied fine
|
||||
DROP TABLE
|
||||
SELECT 1
|
||||
check function idempotence cartodbfied fine
|
||||
1|0101000020E6100000000000000000F0BF000000000000F0BF|0101000020110F0000DB0B4ADA772DFBC077432E49D22DFBC0|this is a sentence
|
||||
1|0101000020E6100000000000000000F0BF000000000000F0BF|this is a sentence
|
||||
check function idempotence cartodbfied fine
|
||||
1|0101000020E6100000000000000000F0BF000000000000F0BF|0101000020110F0000DB0B4ADA772DFBC077432E49D22DFBC0|this is a sentence
|
||||
1|0101000020E6100000000000000000F0BF000000000000F0BF|this is a sentence
|
||||
DROP TABLE
|
||||
SELECT 1
|
||||
srid-unconstrained the_geom cartodbfied fine
|
||||
|
||||
220
test/CDB_FederatedServer.sql
Normal file
220
test/CDB_FederatedServer.sql
Normal file
@@ -0,0 +1,220 @@
|
||||
-- Setup
|
||||
\set QUIET on
|
||||
SET client_min_messages TO error;
|
||||
\set VERBOSITY terse
|
||||
SET SESSION AUTHORIZATION postgres;
|
||||
CREATE EXTENSION postgres_fdw;
|
||||
\set QUIET off
|
||||
|
||||
\echo '## List empty servers shows nothing'
|
||||
SELECT '1.1', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## List non-existent server shows nothing'
|
||||
SELECT '1.2', cartodb.CDB_Federated_Server_List_Servers(server => 'doesNotExist');
|
||||
|
||||
\echo '## Create and list a server works'
|
||||
SELECT '1.3', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@
|
||||
},
|
||||
"credentials": {
|
||||
"username": "fdw_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
SELECT '1.4', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## Create and list a second server works'
|
||||
SELECT '2.1', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote2'::text, config => '{
|
||||
"server": {
|
||||
"dbname": "fdw_target",
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@,
|
||||
"extensions": "postgis",
|
||||
"updatable": "false",
|
||||
"use_remote_estimate": "true",
|
||||
"fetch_size": "1000"
|
||||
},
|
||||
"credentials": {
|
||||
"username": "fdw_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
SELECT '2.2', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## List server by name works'
|
||||
SELECT '2.3', cartodb.CDB_Federated_Server_List_Servers(server => 'myRemote');
|
||||
|
||||
|
||||
\echo '## Re-register a second server works'
|
||||
SELECT '3.1', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote2'::text, config => '{
|
||||
"server": {
|
||||
"dbname": "fdw_target",
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@,
|
||||
"extensions": "postgis",
|
||||
"updatable": "false",
|
||||
"use_remote_estimate": "true",
|
||||
"fetch_size": "1000"
|
||||
},
|
||||
"credentials": {
|
||||
"username": "other_remote_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
SELECT '3.2', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## Unregister server 1 works'
|
||||
SELECT '4.1', cartodb.CDB_Federated_Server_Unregister(server => 'myRemote'::text);
|
||||
SELECT '4.2', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## Unregistering a server that does not exist fails'
|
||||
SELECT '5.1', cartodb.CDB_Federated_Server_Unregister(server => 'doesNotExist'::text);
|
||||
|
||||
\echo '## Unregister the second server works'
|
||||
SELECT '6.1', cartodb.CDB_Federated_Server_Unregister(server => 'myRemote2'::text);
|
||||
SELECT '6.2', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## Create a server with NULL name fails'
|
||||
SELECT '7.0', cartodb.CDB_Federated_Server_Register_PG(server => NULL::text, config => '{ "server": {}, "credentials" : {}}');
|
||||
\echo '## Create a server with NULL config fails'
|
||||
SELECT '7.01', cartodb.CDB_Federated_Server_Register_PG(server => 'empty'::text, config => NULL::jsonb);
|
||||
\echo '## Create a server with empty config fails'
|
||||
SELECT '7.1', cartodb.CDB_Federated_Server_Register_PG(server => 'empty'::text, config => '{}');
|
||||
\echo '## Create a server without credentials fails'
|
||||
SELECT '7.2', cartodb.CDB_Federated_Server_Register_PG(server => 'empty'::text, config => '{
|
||||
"server": {
|
||||
"dbname": "fdw_target",
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@,
|
||||
"extensions": "postgis",
|
||||
"updatable": "false",
|
||||
"use_remote_estimate": "true",
|
||||
"fetch_size": "1000"
|
||||
}
|
||||
}'::jsonb);
|
||||
\echo '## Create a server with empty credentials works'
|
||||
SELECT '7.3', cartodb.CDB_Federated_Server_Register_PG(server => 'empty'::text, config => '{
|
||||
"server": {
|
||||
"dbname": "fdw_target",
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@,
|
||||
"extensions": "postgis",
|
||||
"updatable": "false",
|
||||
"use_remote_estimate": "true",
|
||||
"fetch_size": "1000"
|
||||
},
|
||||
"credentials": { }
|
||||
}'::jsonb);
|
||||
SELECT '7.4', cartodb.CDB_Federated_Server_List_Servers();
|
||||
SELECT '7.5', cartodb.CDB_Federated_Server_Unregister(server => 'empty'::text);
|
||||
\echo '## Create a server without options fails'
|
||||
SELECT '7.6', cartodb.CDB_Federated_Server_Register_PG(server => 'empty'::text, config => '{
|
||||
"credentials": {
|
||||
"username": "other_remote_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
|
||||
\echo '## Create a server with special characters works'
|
||||
SELECT '8.1', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote" or''not'::text, config => '{
|
||||
"server": {
|
||||
"dbname": "fdw target",
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@,
|
||||
"extensions": "postgis",
|
||||
"updatable": "false",
|
||||
"use_remote_estimate": "true",
|
||||
"fetch_size": "1000"
|
||||
},
|
||||
"credentials": {
|
||||
"username": "fdw user",
|
||||
"password": "foo barino"
|
||||
}
|
||||
}'::jsonb);
|
||||
SELECT '8.2', cartodb.CDB_Federated_Server_List_Servers();
|
||||
SELECT '8.3', cartodb.CDB_Federated_Server_Unregister(server => 'myRemote" or''not'::text);
|
||||
|
||||
-- Test permissions
|
||||
\set QUIET on
|
||||
CREATE ROLE cdb_fs_tester LOGIN PASSWORD 'cdb_fs_passwd';
|
||||
GRANT CONNECT ON DATABASE contrib_regression TO cdb_fs_tester;
|
||||
\set QUIET off
|
||||
|
||||
SELECT '9.1', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote3'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@
|
||||
},
|
||||
"credentials": {
|
||||
"username": "fdw_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
|
||||
\c contrib_regression cdb_fs_tester
|
||||
|
||||
\echo '## All users are able to list servers'
|
||||
SELECT '9.2', cartodb.CDB_Federated_Server_List_Servers();
|
||||
|
||||
\echo '## Only superadmins can create servers'
|
||||
SELECT '9.3', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote4'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@
|
||||
},
|
||||
"credentials": {
|
||||
"username": "fdw_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
|
||||
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Granting access to a user works'
|
||||
SELECT '9.5', cartodb.CDB_Federated_Server_Grant_Access(server => 'myRemote3', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT '9.55', cartodb.CDB_Federated_Server_List_Servers();
|
||||
\c contrib_regression postgres
|
||||
SELECT '9.6', cartodb.CDB_Federated_Server_Grant_Access(server => 'does not exist', db_role => 'cdb_fs_tester'::name);
|
||||
SELECT '9.7', cartodb.CDB_Federated_Server_Grant_Access(server => 'myRemote3', db_role => 'does not exist'::name);
|
||||
|
||||
\echo '## Granting access again raises a notice'
|
||||
SELECT '9.8', cartodb.CDB_Federated_Server_Grant_Access(server => 'myRemote3', db_role => 'cdb_fs_tester'::name);
|
||||
|
||||
\echo '## Revoking access to a user works'
|
||||
SELECT '9.9', cartodb.CDB_Federated_Server_Revoke_Access(server => 'myRemote3', db_role => 'cdb_fs_tester'::name);
|
||||
SELECT '9.10', cartodb.CDB_Federated_Server_Grant_Access(server => 'myRemote3', db_role => 'cdb_fs_tester'::name);
|
||||
|
||||
\echo '## Unregistering a server with active grants works'
|
||||
SELECT '9.11', cartodb.CDB_Federated_Server_Unregister(server => 'myRemote3'::text);
|
||||
|
||||
|
||||
\echo '## A user with granted access can not drop a server'
|
||||
SELECT '10.1', cartodb.CDB_Federated_Server_Register_PG(server => 'myRemote4'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@
|
||||
},
|
||||
"credentials": {
|
||||
"username": "fdw_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}'::jsonb);
|
||||
SELECT '10.2', cartodb.CDB_Federated_Server_Grant_Access(server => 'myRemote4', db_role => 'cdb_fs_tester'::name);
|
||||
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT '10.3', cartodb.CDB_Federated_Server_Unregister(server => 'myRemote4'::text);
|
||||
|
||||
\c contrib_regression postgres
|
||||
SELECT '10.4', cartodb.CDB_Federated_Server_Unregister(server => 'myRemote4'::text);
|
||||
|
||||
|
||||
-- Cleanup
|
||||
\set QUIET on
|
||||
REVOKE CONNECT ON DATABASE contrib_regression FROM cdb_fs_tester;
|
||||
DROP ROLE cdb_fs_tester;
|
||||
DROP EXTENSION postgres_fdw;
|
||||
\set QUIET off
|
||||
125
test/CDB_FederatedServerDiagnostics.sql
Normal file
125
test/CDB_FederatedServerDiagnostics.sql
Normal file
@@ -0,0 +1,125 @@
|
||||
-- ===================================================================
|
||||
-- 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);
|
||||
|
||||
SELECT 'C2', cartodb.CDB_Federated_Server_Register_PG(server => 'wrong-port'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": "12345"
|
||||
},
|
||||
"credentials": {
|
||||
"username": "cdb_fs_tester",
|
||||
"password": "cdb_fs_passwd"
|
||||
}
|
||||
}'::jsonb);
|
||||
|
||||
SELECT 'C3', cartodb.CDB_Federated_Server_Register_PG(server => 'loopback-no-port'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost"
|
||||
},
|
||||
"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;
|
||||
|
||||
\echo '%% It returns network latency stats to the remote server: min <= avg <= max'
|
||||
WITH latency AS (
|
||||
SELECT CDB_Federated_Server_Diagnostics('loopback')->'server_latency_ms' ms
|
||||
) SELECT '2.1', (latency.ms->'min')::text::float <= (latency.ms->'avg')::text::float, (latency.ms->'avg')::text::float <= (latency.ms->'max')::text::float
|
||||
FROM latency;
|
||||
|
||||
\echo '%% Latency stats: 0 <= min <= max <= 1000 ms (local connection)'
|
||||
WITH latency AS (
|
||||
SELECT CDB_Federated_Server_Diagnostics('loopback')->'server_latency_ms' ms
|
||||
) SELECT '2.2', 0.0 <= (latency.ms->'min')::text::float, (latency.ms->'max')::text::float <= 1000.0
|
||||
FROM latency;
|
||||
|
||||
\echo '%% Latency stats: stdev > 0'
|
||||
WITH latency AS (
|
||||
SELECT CDB_Federated_Server_Diagnostics('loopback')->'server_latency_ms' ms
|
||||
) SELECT '2.3', (latency.ms->'stdev')::text::float >= 0.0
|
||||
FROM latency;
|
||||
|
||||
\echo '%% It raises an error if the wrong port is provided'
|
||||
SELECT '3.0', cartodb.CDB_Federated_Server_Diagnostics(server => 'wrong-port');
|
||||
|
||||
\echo '%% Latency stats: can get them on default PG port 5432 when not provided'
|
||||
WITH latency AS (
|
||||
SELECT CDB_Federated_Server_Diagnostics('loopback-no-port')->'server_latency_ms' ms
|
||||
) SELECT '2.4', 0.0 <= (latency.ms->'min')::text::float, (latency.ms->'max')::text::float <= 1000.0
|
||||
FROM latency;
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Cleanup
|
||||
-- ===================================================================
|
||||
\set QUIET on
|
||||
SELECT 'D1', cartodb.CDB_Federated_Server_Unregister(server => 'loopback'::text);
|
||||
SELECT 'D2', cartodb.CDB_Federated_Server_Unregister(server => 'wrong-port'::text);
|
||||
SELECT 'D3', cartodb.CDB_Federated_Server_Unregister(server => 'loopback-no-port'::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
|
||||
28
test/CDB_FederatedServerDiagnostics_expect
Normal file
28
test/CDB_FederatedServerDiagnostics_expect
Normal file
@@ -0,0 +1,28 @@
|
||||
C1|
|
||||
C2|
|
||||
C3|
|
||||
%% 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
|
||||
%% It returns network latency stats to the remote server: min <= avg <= max
|
||||
2.1|t|t
|
||||
%% Latency stats: 0 <= min <= max <= 1000 ms (local connection)
|
||||
2.2|t|t
|
||||
%% Latency stats: stdev > 0
|
||||
2.3|t
|
||||
%% It raises an error if the wrong port is provided
|
||||
ERROR: could not connect to server "cdb_fs_wrong-port"
|
||||
%% Latency stats: can get them on default PG port 5432 when not provided
|
||||
2.4|t|t
|
||||
D1|
|
||||
D2|
|
||||
D3|
|
||||
319
test/CDB_FederatedServerListRemote.sql
Normal file
319
test/CDB_FederatedServerListRemote.sql
Normal file
@@ -0,0 +1,319 @@
|
||||
-- ===================================================================
|
||||
-- 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 ROLE cdb_fs_tester2 LOGIN PASSWORD 'cdb_fs_passwd2';
|
||||
GRANT CONNECT ON DATABASE contrib_regression TO cdb_fs_tester2;
|
||||
|
||||
-- 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);
|
||||
|
||||
SELECT 'C2', cartodb.CDB_Federated_Server_Register_PG(server => 'loopback2'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@
|
||||
},
|
||||
"credentials": {
|
||||
"username": "cdb_fs_tester",
|
||||
"password": "cdb_fs_passwd"
|
||||
}
|
||||
}'::jsonb);
|
||||
|
||||
-- ===================================================================
|
||||
-- Setup 1
|
||||
-- ===================================================================
|
||||
\c cdb_fs_tester cdb_fs_tester
|
||||
|
||||
CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz');
|
||||
CREATE SCHEMA "S 1";
|
||||
CREATE TABLE "S 1"."T 1" (
|
||||
"C 1" int NOT NULL,
|
||||
c2 int NOT NULL,
|
||||
c3 text,
|
||||
c4 timestamptz,
|
||||
c5 timestamp,
|
||||
c6 varchar(10),
|
||||
c7 char(10),
|
||||
c8 user_enum,
|
||||
CONSTRAINT t1_pkey PRIMARY KEY ("C 1")
|
||||
);
|
||||
CREATE TABLE "S 1"."T 2" (
|
||||
c1 int NOT NULL,
|
||||
c2 text,
|
||||
CONSTRAINT t2_pkey PRIMARY KEY (c1)
|
||||
);
|
||||
CREATE TABLE "S 1"."T 3" (
|
||||
c1 int NOT NULL,
|
||||
c2 int NOT NULL,
|
||||
c3 text,
|
||||
CONSTRAINT t3_pkey PRIMARY KEY (c1)
|
||||
);
|
||||
CREATE TABLE "S 1"."T 4" (
|
||||
c1 int NOT NULL,
|
||||
c2 int NOT NULL,
|
||||
c3 text,
|
||||
CONSTRAINT t4_pkey PRIMARY KEY (c1)
|
||||
);
|
||||
|
||||
-- Disable autovacuum for these tables to avoid unexpected effects of that
|
||||
ALTER TABLE "S 1"."T 1" SET (autovacuum_enabled = 'false');
|
||||
ALTER TABLE "S 1"."T 2" SET (autovacuum_enabled = 'false');
|
||||
ALTER TABLE "S 1"."T 3" SET (autovacuum_enabled = 'false');
|
||||
ALTER TABLE "S 1"."T 4" SET (autovacuum_enabled = 'false');
|
||||
|
||||
\c contrib_regression postgres
|
||||
SET client_min_messages TO notice;
|
||||
\set VERBOSITY terse
|
||||
\set QUIET off
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Test listing remote schemas
|
||||
-- ===================================================================
|
||||
\echo '## Test listing of remote schemas without permissions before the first instantiation (rainy day)'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote schemas (sunny day)'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback');
|
||||
|
||||
\echo '## Test listing of remote schemas without permissions after the first instantiation (rainy day)'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote schemas with permissions (sunny day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server => 'loopback', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote schemas without permissions after revoking access (rainy day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Revoke_Access(server => 'loopback', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote schemas (rainy day): Server does not exist'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'Does Not Exist');
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Test listing remote tables
|
||||
-- ===================================================================
|
||||
|
||||
\echo '## Test listing of remote tables without permissions before the first instantiation (rainy day)'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'S 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote tables (sunny day)'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'S 1');
|
||||
|
||||
\echo '## Test listing of remote tables without permissions after the first instantiation (rainy day)'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'S 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote tables with permissions (sunny day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server => 'loopback', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'S 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote tables without permissions after revoking access (rainy day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Revoke_Access(server => 'loopback', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'S 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote tables (rainy day): Server does not exist'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'Does Not Exist', remote_schema => 'S 1');
|
||||
|
||||
\echo '## Test listing of remote tables (rainy day): Remote schema does not exist'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'Does Not Exist');
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Test listing remote columns
|
||||
-- ===================================================================
|
||||
|
||||
\echo '## Test listing of remote columns without permissions before the first instantiation (rainy day)'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote columns (sunny day)'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
|
||||
\echo '## Test listing of remote columns without permissions after the first instantiation (rainy day)'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote columns with permissions (sunny day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server => 'loopback', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote columns without permissions after revoking access (rainy day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Revoke_Access(server => 'loopback', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
\c contrib_regression postgres
|
||||
|
||||
\echo '## Test listing of remote columns (rainy day): Server does not exist'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'Does Not Exist', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
|
||||
\echo '## Test listing of remote columns (rainy day): Remote schema does not exist'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'Does Not Exist', remote_table => 'T 1');
|
||||
|
||||
\echo '## Test listing of remote columns (rainy day): Remote table does not exist'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'Does Not Exist');
|
||||
|
||||
\echo '## Test listing of remote columns (rainy day): Remote table is NULL'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => NULL::text);
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Test that using a different user to list tables and dropping it
|
||||
-- does not break the server: We use loopback2 as it's in a clean state
|
||||
-- ===================================================================
|
||||
|
||||
|
||||
\echo '## Test listing of remote objects with permissions (sunny day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server => 'loopback2', db_role => 'cdb_fs_tester2'::name);
|
||||
\c contrib_regression cdb_fs_tester2
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback2');
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback2', remote_schema => 'S 1');
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback2', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
|
||||
\c contrib_regression postgres
|
||||
\echo '## Test that dropping the granted user works fine (sunny day)'
|
||||
REVOKE CONNECT ON DATABASE contrib_regression FROM cdb_fs_tester2;
|
||||
DROP ROLE cdb_fs_tester2;
|
||||
|
||||
\echo '## Test listing of remote objects with other user still works (sunny day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server => 'loopback2', db_role => 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback2');
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback2', remote_schema => 'S 1');
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback2', remote_schema => 'S 1', remote_table => 'T 1');
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Cleanup 1
|
||||
-- ===================================================================
|
||||
\set QUIET on
|
||||
|
||||
\c cdb_fs_tester cdb_fs_tester
|
||||
DROP TABLE "S 1". "T 1";
|
||||
DROP TABLE "S 1". "T 2";
|
||||
DROP TABLE "S 1". "T 3";
|
||||
DROP TABLE "S 1". "T 4";
|
||||
|
||||
DROP SCHEMA "S 1";
|
||||
DROP TYPE user_enum;
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Setup 2: Using Postgis too
|
||||
-- ===================================================================
|
||||
|
||||
\c cdb_fs_tester postgres
|
||||
|
||||
CREATE EXTENSION postgis;
|
||||
|
||||
\c cdb_fs_tester cdb_fs_tester
|
||||
|
||||
CREATE SCHEMA "S 1";
|
||||
CREATE TABLE "S 1"."T 5" (
|
||||
geom geometry(Geometry,4326),
|
||||
geom_wm geometry(GeometryZ,3857),
|
||||
geo_nosrid geometry,
|
||||
geog geography
|
||||
);
|
||||
|
||||
\c contrib_regression postgres
|
||||
SET client_min_messages TO notice;
|
||||
\set VERBOSITY terse
|
||||
\set QUIET off
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Test the listing functions
|
||||
-- ===================================================================
|
||||
|
||||
\echo '## Test listing of remote geometry columns (sunny day)'
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 5');
|
||||
\echo '## Test listing of remote geometry columns (sunny day) - Rerun'
|
||||
-- Rerun should be ok
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Columns(server => 'loopback', remote_schema => 'S 1', remote_table => 'T 5');
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- Test invalid password
|
||||
-- ===================================================================
|
||||
|
||||
\echo '## Check error message with invalid password (rainy day)'
|
||||
SELECT cartodb.CDB_Federated_Server_Register_PG(server => 'loopback_invalid'::text, config => '{
|
||||
"server": {
|
||||
"host": "localhost",
|
||||
"port": @@PGPORT@@
|
||||
},
|
||||
"credentials": {
|
||||
"username": "cdb_fs_tester",
|
||||
"password": "wrong password"
|
||||
}
|
||||
}'::jsonb);
|
||||
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Schemas(server => 'loopback_invalid');
|
||||
|
||||
SELECT cartodb.CDB_Federated_Server_Unregister(server => 'loopback_invalid'::text);
|
||||
|
||||
-- ===================================================================
|
||||
-- Cleanup 2
|
||||
-- ===================================================================
|
||||
\set QUIET on
|
||||
|
||||
\c cdb_fs_tester cdb_fs_tester
|
||||
DROP TABLE "S 1". "T 5";
|
||||
|
||||
DROP SCHEMA "S 1";
|
||||
|
||||
\c contrib_regression postgres
|
||||
\set QUIET on
|
||||
SET client_min_messages TO error;
|
||||
\set VERBOSITY terse
|
||||
|
||||
SELECT 'D1', cartodb.CDB_Federated_Server_Unregister(server => 'loopback'::text);
|
||||
SELECT 'D2', cartodb.CDB_Federated_Server_Unregister(server => 'loopback2'::text);
|
||||
|
||||
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
|
||||
162
test/CDB_FederatedServerListRemote_expect
Normal file
162
test/CDB_FederatedServerListRemote_expect
Normal file
@@ -0,0 +1,162 @@
|
||||
C1|
|
||||
C2|
|
||||
## Test listing of remote schemas without permissions before the first instantiation (rainy day)
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote schemas (sunny day)
|
||||
S 1
|
||||
information_schema
|
||||
public
|
||||
## Test listing of remote schemas without permissions after the first instantiation (rainy day)
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote schemas with permissions (sunny day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
S 1
|
||||
information_schema
|
||||
public
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote schemas without permissions after revoking access (rainy day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote schemas (rainy day): Server does not exist
|
||||
ERROR: Server "Does Not Exist" does not exist
|
||||
## Test listing of remote tables without permissions before the first instantiation (rainy day)
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote tables (sunny day)
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback"
|
||||
f|T 1|||||[{"Name" : "C 1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}, {"Name" : "c4", "Type" : "timestamp with time zone"}, {"Name" : "c5", "Type" : "timestamp without time zone"}, {"Name" : "c6", "Type" : "character varying"}, {"Name" : "c7", "Type" : "character"}, {"Name" : "c8", "Type" : "USER-DEFINED"}]
|
||||
f|T 2|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "text"}]
|
||||
f|T 3|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
f|T 4|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
## Test listing of remote tables without permissions after the first instantiation (rainy day)
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote tables with permissions (sunny day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback"
|
||||
f|T 1|||||[{"Name" : "C 1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}, {"Name" : "c4", "Type" : "timestamp with time zone"}, {"Name" : "c5", "Type" : "timestamp without time zone"}, {"Name" : "c6", "Type" : "character varying"}, {"Name" : "c7", "Type" : "character"}, {"Name" : "c8", "Type" : "USER-DEFINED"}]
|
||||
f|T 2|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "text"}]
|
||||
f|T 3|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
f|T 4|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote tables without permissions after revoking access (rainy day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote tables (rainy day): Server does not exist
|
||||
ERROR: Server "Does Not Exist" does not exist
|
||||
## Test listing of remote tables (rainy day): Remote schema does not exist
|
||||
## Test listing of remote columns without permissions before the first instantiation (rainy day)
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote columns (sunny day)
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback"
|
||||
C 1|integer
|
||||
c2|integer
|
||||
c3|text
|
||||
c4|timestamp with time zone
|
||||
c5|timestamp without time zone
|
||||
c6|character varying
|
||||
c7|character
|
||||
c8|USER-DEFINED
|
||||
## Test listing of remote columns without permissions after the first instantiation (rainy day)
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote columns with permissions (sunny day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback"
|
||||
C 1|integer
|
||||
c2|integer
|
||||
c3|text
|
||||
c4|timestamp with time zone
|
||||
c5|timestamp without time zone
|
||||
c6|character varying
|
||||
c7|character
|
||||
c8|USER-DEFINED
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote columns without permissions after revoking access (rainy day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test listing of remote columns (rainy day): Server does not exist
|
||||
ERROR: Server "Does Not Exist" does not exist
|
||||
## Test listing of remote columns (rainy day): Remote schema does not exist
|
||||
## Test listing of remote columns (rainy day): Remote table does not exist
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback"
|
||||
## Test listing of remote columns (rainy day): Remote table is NULL
|
||||
ERROR: Remote table name cannot be NULL
|
||||
## Test listing of remote objects with permissions (sunny day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester2".
|
||||
S 1
|
||||
information_schema
|
||||
public
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback2"
|
||||
f|T 1|||||[{"Name" : "C 1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}, {"Name" : "c4", "Type" : "timestamp with time zone"}, {"Name" : "c5", "Type" : "timestamp without time zone"}, {"Name" : "c6", "Type" : "character varying"}, {"Name" : "c7", "Type" : "character"}, {"Name" : "c8", "Type" : "USER-DEFINED"}]
|
||||
f|T 2|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "text"}]
|
||||
f|T 3|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
f|T 4|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback2"
|
||||
C 1|integer
|
||||
c2|integer
|
||||
c3|text
|
||||
c4|timestamp with time zone
|
||||
c5|timestamp without time zone
|
||||
c6|character varying
|
||||
c7|character
|
||||
c8|USER-DEFINED
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Test that dropping the granted user works fine (sunny day)
|
||||
REVOKE
|
||||
DROP ROLE
|
||||
## Test listing of remote objects with other user still works (sunny day)
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
S 1
|
||||
information_schema
|
||||
public
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback2"
|
||||
f|T 1|||||[{"Name" : "C 1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}, {"Name" : "c4", "Type" : "timestamp with time zone"}, {"Name" : "c5", "Type" : "timestamp without time zone"}, {"Name" : "c6", "Type" : "character varying"}, {"Name" : "c7", "Type" : "character"}, {"Name" : "c8", "Type" : "USER-DEFINED"}]
|
||||
f|T 2|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "text"}]
|
||||
f|T 3|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
f|T 4|||||[{"Name" : "c1", "Type" : "integer"}, {"Name" : "c2", "Type" : "integer"}, {"Name" : "c3", "Type" : "text"}]
|
||||
INFO: Could not find Postgis installation in the remote "public" schema in server "loopback2"
|
||||
C 1|integer
|
||||
c2|integer
|
||||
c3|text
|
||||
c4|timestamp with time zone
|
||||
c5|timestamp without time zone
|
||||
c6|character varying
|
||||
c7|character
|
||||
c8|USER-DEFINED
|
||||
## Test listing of remote geometry columns (sunny day)
|
||||
geo_nosrid|GEOMETRY,0
|
||||
geog|Geometry,0
|
||||
geom|GEOMETRY,4326
|
||||
geom_wm|GEOMETRY,3857
|
||||
## Test listing of remote geometry columns (sunny day) - Rerun
|
||||
geo_nosrid|GEOMETRY,0
|
||||
geog|Geometry,0
|
||||
geom|GEOMETRY,4326
|
||||
geom_wm|GEOMETRY,3857
|
||||
## Check error message with invalid password (rainy day)
|
||||
|
||||
ERROR: could not connect to server "cdb_fs_loopback_invalid"
|
||||
|
||||
D1|
|
||||
D2|
|
||||
405
test/CDB_FederatedServerTables.sql
Normal file
405
test/CDB_FederatedServerTables.sql
Normal file
@@ -0,0 +1,405 @@
|
||||
-- ===================================================================
|
||||
-- create FDW objects
|
||||
-- ===================================================================
|
||||
\set QUIET on
|
||||
SET client_min_messages TO error;
|
||||
\set VERBOSITY terse
|
||||
|
||||
CREATE EXTENSION postgres_fdw;
|
||||
|
||||
-- We create a username following the same steps as organization members
|
||||
CREATE ROLE cdb_fs_tester LOGIN PASSWORD 'cdb_fs_passwd';
|
||||
GRANT CONNECT ON DATABASE contrib_regression TO cdb_fs_tester;
|
||||
|
||||
CREATE ROLE cdb_fs_tester2 LOGIN PASSWORD 'cdb_fs_passwd2';
|
||||
GRANT CONNECT ON DATABASE contrib_regression TO cdb_fs_tester2;
|
||||
|
||||
-- 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);
|
||||
|
||||
|
||||
-- ===================================================================
|
||||
-- create objects used through FDW loopback server
|
||||
-- ===================================================================
|
||||
|
||||
\c cdb_fs_tester postgres
|
||||
|
||||
CREATE EXTENSION postgis;
|
||||
|
||||
\c cdb_fs_tester cdb_fs_tester
|
||||
|
||||
CREATE SCHEMA remote_schema;
|
||||
CREATE TABLE remote_schema.remote_geom(id int, another_field text, geom geometry(Geometry,4326));
|
||||
|
||||
INSERT INTO remote_schema.remote_geom VALUES (1, 'patata', 'SRID=4326;POINT(1 1)'::geometry);
|
||||
INSERT INTO remote_schema.remote_geom VALUES (2, 'patata2', 'SRID=4326;POINT(2 2)'::geometry);
|
||||
|
||||
CREATE TABLE remote_schema.remote_geom2(cartodb_id bigint, another_field text, the_geom geometry(Geometry,4326), the_geom_webmercator geometry(Geometry,3857));
|
||||
|
||||
INSERT INTO remote_schema.remote_geom2 VALUES (3, 'patata', 'SRID=4326;POINT(3 3)'::geometry, 'SRID=3857;POINT(3 3)');
|
||||
|
||||
CREATE TABLE remote_schema.remote_other(id bigint, field text, field2 text);
|
||||
INSERT INTO remote_schema.remote_other VALUES (1, 'delicious', 'potatoes');
|
||||
|
||||
CREATE TABLE remote_schema.remote_geom3(id bigint, geom geometry(Geometry,4326), geom_mercator geometry(Geometry,3857));
|
||||
|
||||
-- ===================================================================
|
||||
-- Test the listing functions
|
||||
-- ===================================================================
|
||||
|
||||
\c contrib_regression postgres
|
||||
SET client_min_messages TO error;
|
||||
\set VERBOSITY terse
|
||||
\set QUIET off
|
||||
|
||||
\echo '## Registering an existing table works'
|
||||
SELECT 'R1', cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
SELECT 'S1', cartodb_id, ST_AsText(the_geom), another_field FROM cdb_fs_loopback.remote_geom;
|
||||
|
||||
Select * FROM CDB_Federated_Server_List_Remote_Tables(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema'
|
||||
);
|
||||
|
||||
\echo '## Registering another existing table works'
|
||||
SELECT 'R2', cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom2',
|
||||
id_column => 'cartodb_id',
|
||||
geom_column => 'the_geom',
|
||||
webmercator_column => 'the_geom_webmercator',
|
||||
local_name => 'myFullTable'
|
||||
);
|
||||
|
||||
SELECT 'S2', cartodb_id, ST_AsText(the_geom), another_field FROM cdb_fs_loopback."myFullTable";
|
||||
Select * FROM CDB_Federated_Server_List_Remote_Tables(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema'
|
||||
);
|
||||
|
||||
\echo '## Re-registering a table works'
|
||||
SELECT 'R3', cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom2',
|
||||
id_column => 'cartodb_id',
|
||||
-- Switch geom and geom_column on purpose to force ST_Transform to be used
|
||||
geom_column => 'the_geom_webmercator',
|
||||
webmercator_column => 'the_geom',
|
||||
local_name => 'different_name'
|
||||
);
|
||||
|
||||
-- The old view should dissapear
|
||||
SELECT 'S3_old', cartodb_id, another_field FROM cdb_fs_loopback."myFullTable";
|
||||
-- And the new appear
|
||||
SELECT 'S3_new', cartodb_id, another_field FROM cdb_fs_loopback.different_name;
|
||||
|
||||
\echo '## Unregistering works'
|
||||
-- Deregistering the first table
|
||||
SELECT 'U1', cartodb.CDB_Federated_Table_Unregister(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom'
|
||||
);
|
||||
-- Selecting from the created view should fail now
|
||||
SELECT 'UCheck1', cartodb_id, ST_AsText(the_geom), another_field FROM remote_geom;
|
||||
|
||||
Select * FROM CDB_Federated_Server_List_Remote_Tables(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema'
|
||||
);
|
||||
|
||||
-- ===================================================================
|
||||
-- Test input
|
||||
-- ===================================================================
|
||||
|
||||
\echo '## Registering a table: Invalid server fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'Does not exist',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: NULL server fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => NULL::text,
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: Invalid schema fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'Does not exist',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: NULL schema fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => NULL::text,
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: Invalid table fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'Does not exist',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: NULL table fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => NULL::text,
|
||||
id_column => 'id',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: Invalid id fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'Does not exist',
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: NULL id fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => NULL::text,
|
||||
geom_column => 'geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: Invalid geom_column fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'Does not exists'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: NULL geom_column is OK: Reuses geom_mercator'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => NULL::text,
|
||||
webmercator_column => 'geom'
|
||||
);
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema') where remote_table = 'remote_geom';
|
||||
|
||||
SELECT cartodb.CDB_Federated_Table_Unregister(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: Invalid webmercator_column fails'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
webmercator_column => 'Does not exists'
|
||||
);
|
||||
|
||||
\echo '## Registering a table: NULL webmercator_column is OK: Reuses geom'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
webmercator_column => NULL::text
|
||||
);
|
||||
SELECT * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema') where remote_table = 'remote_geom';
|
||||
SELECT cartodb.CDB_Federated_Table_Unregister(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom'
|
||||
);
|
||||
|
||||
\echo '##Registering a table with extra columns show the correct information'
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom3',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
webmercator_column => 'geom_mercator'
|
||||
);
|
||||
Select * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema') where remote_table = 'remote_geom3';
|
||||
SELECT cartodb.CDB_Federated_Table_Unregister(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom3'
|
||||
);
|
||||
|
||||
-- ===================================================================
|
||||
-- Test conflicts
|
||||
-- ===================================================================
|
||||
|
||||
\echo '## Target conflict is handled nicely: Table'
|
||||
CREATE TABLE cdb_fs_loopback.localtable (a integer);
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
local_name => 'localtable');
|
||||
|
||||
\echo '## Target conflict is handled nicely: View'
|
||||
CREATE VIEW cdb_fs_loopback.localtable2 AS Select * from cdb_fs_loopback.localtable;
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
local_name => 'localtable2');
|
||||
|
||||
DROP VIEW cdb_fs_loopback.localtable2;
|
||||
DROP TABLE cdb_fs_loopback.localtable;
|
||||
|
||||
-- ===================================================================
|
||||
-- Test permissions
|
||||
-- ===================================================================
|
||||
|
||||
|
||||
\echo '## Registering tables does not work without permissions'
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
local_name => 'localtable');
|
||||
|
||||
\echo '## Normal users can not write in the import schema'
|
||||
CREATE TABLE cdb_fs_loopback.localtable (a integer);
|
||||
|
||||
\echo '## Listing remote tables does not work without permissions'
|
||||
Select * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema');
|
||||
|
||||
\echo '## Registering tables works with granted permissions'
|
||||
\c contrib_regression postgres
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server := 'loopback', db_role := 'cdb_fs_tester'::name);
|
||||
\c contrib_regression cdb_fs_tester
|
||||
SELECT cartodb.CDB_Federated_Table_Register(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom',
|
||||
id_column => 'id',
|
||||
geom_column => 'geom',
|
||||
local_name => 'localtable');
|
||||
|
||||
\echo '## Listing remote tables works with granted permissions'
|
||||
Select * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema');
|
||||
|
||||
\echo '## Selecting from a registered table with granted permissions works'
|
||||
Select cartodb_id, ST_AsText(the_geom) from cdb_fs_loopback.localtable;
|
||||
|
||||
\echo '## Selecting from a registered table without permissions does not work'
|
||||
\c contrib_regression cdb_fs_tester2
|
||||
CREATE OR REPLACE FUNCTION catch_permission_error(query text)
|
||||
RETURNS bool
|
||||
AS $$
|
||||
BEGIN
|
||||
EXECUTE query;
|
||||
RETURN FALSE;
|
||||
EXCEPTION
|
||||
WHEN insufficient_privilege THEN
|
||||
RETURN TRUE;
|
||||
WHEN OTHERS THEN
|
||||
RAISE WARNING 'Exception %', sqlstate;
|
||||
RETURN FALSE;
|
||||
END
|
||||
$$ LANGUAGE 'plpgsql';
|
||||
Select catch_permission_error($$SELECT cartodb_id, ST_AsText(the_geom) from cdb_fs_loopback.localtable$$);
|
||||
DROP FUNCTION catch_permission_error(text);
|
||||
|
||||
\echo '## Deleting a registered table without permissions does not work'
|
||||
SELECT cartodb.CDB_Federated_Table_Unregister(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom'
|
||||
);
|
||||
|
||||
\echo '## Only the owner can grant permissions over the server'
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server := 'loopback', db_role := 'cdb_fs_tester2'::name);
|
||||
|
||||
\echo '## Everything works for a different user when granted permissions'
|
||||
\c contrib_regression postgres
|
||||
SELECT cartodb.CDB_Federated_Server_Grant_Access(server := 'loopback', db_role := 'cdb_fs_tester2'::name);
|
||||
\c contrib_regression cdb_fs_tester2
|
||||
Select * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema');
|
||||
Select cartodb_id, ST_AsText(the_geom) from cdb_fs_loopback.localtable;
|
||||
|
||||
\echo '## A different user can unregister a table'
|
||||
SELECT cartodb.CDB_Federated_Table_Unregister(
|
||||
server => 'loopback',
|
||||
remote_schema => 'remote_schema',
|
||||
remote_table => 'remote_geom'
|
||||
);
|
||||
Select * FROM cartodb.CDB_Federated_Server_List_Remote_Tables(server => 'loopback', remote_schema => 'remote_schema');
|
||||
|
||||
\echo '## Only the owner can revoke permissions over the server'
|
||||
SELECT cartodb.CDB_Federated_Server_Revoke_Access(server := 'loopback', db_role := 'cdb_fs_tester'::name);
|
||||
|
||||
-- ===================================================================
|
||||
-- Cleanup
|
||||
-- ===================================================================
|
||||
|
||||
\set QUIET on
|
||||
\c contrib_regression postgres
|
||||
SET client_min_messages TO error;
|
||||
\set VERBOSITY terse
|
||||
|
||||
REVOKE CONNECT ON DATABASE contrib_regression FROM cdb_fs_tester2;
|
||||
DROP ROLE cdb_fs_tester2;
|
||||
|
||||
SELECT 'D1', cartodb.CDB_Federated_Server_Unregister(server := 'loopback'::text);
|
||||
DROP DATABASE cdb_fs_tester;
|
||||
REVOKE CONNECT ON DATABASE contrib_regression FROM cdb_fs_tester;
|
||||
DROP ROLE cdb_fs_tester;
|
||||
DROP EXTENSION postgres_fdw;
|
||||
\set QUIET off
|
||||
116
test/CDB_FederatedServerTables_expect
Normal file
116
test/CDB_FederatedServerTables_expect
Normal file
@@ -0,0 +1,116 @@
|
||||
C1|
|
||||
## Registering an existing table works
|
||||
R1|
|
||||
S1|1|POINT(1 1)|patata
|
||||
S1|2|POINT(2 2)|patata2
|
||||
t|remote_geom|cdb_fs_loopback.remote_geom|id|geom|geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
f|remote_geom2|||||[{"Name" : "another_field", "Type" : "text"}, {"Name" : "cartodb_id", "Type" : "bigint"}, {"Name" : "the_geom", "Type" : "GEOMETRY,4326"}, {"Name" : "the_geom_webmercator", "Type" : "GEOMETRY,3857"}]
|
||||
f|remote_geom3|||||[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
f|remote_other|||||[{"Name" : "field", "Type" : "text"}, {"Name" : "field2", "Type" : "text"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
## Registering another existing table works
|
||||
R2|
|
||||
S2|3|POINT(3 3)|patata
|
||||
t|remote_geom|cdb_fs_loopback.remote_geom|id|geom|geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
t|remote_geom2|cdb_fs_loopback."myFullTable"|cartodb_id|the_geom|the_geom_webmercator|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "cartodb_id", "Type" : "bigint"}, {"Name" : "the_geom", "Type" : "GEOMETRY,4326"}, {"Name" : "the_geom_webmercator", "Type" : "GEOMETRY,3857"}]
|
||||
f|remote_geom3|||||[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
f|remote_other|||||[{"Name" : "field", "Type" : "text"}, {"Name" : "field2", "Type" : "text"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
## Re-registering a table works
|
||||
R3|
|
||||
ERROR: relation "cdb_fs_loopback.myFullTable" does not exist at character 49
|
||||
S3_new|3|patata
|
||||
## Unregistering works
|
||||
U1|
|
||||
ERROR: relation "remote_geom" does not exist at character 71
|
||||
f|remote_geom|||||[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
t|remote_geom2|cdb_fs_loopback.different_name|cartodb_id|the_geom_webmercator|the_geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "cartodb_id", "Type" : "bigint"}, {"Name" : "the_geom", "Type" : "GEOMETRY,4326"}, {"Name" : "the_geom_webmercator", "Type" : "GEOMETRY,3857"}]
|
||||
f|remote_geom3|||||[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
f|remote_other|||||[{"Name" : "field", "Type" : "text"}, {"Name" : "field2", "Type" : "text"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
## Registering a table: Invalid server fails
|
||||
ERROR: Server "Does not exist" does not exist
|
||||
## Registering a table: NULL server fails
|
||||
ERROR: Server name cannot be NULL
|
||||
## Registering a table: Invalid schema fails
|
||||
ERROR: Could not import schema "Does not exist" of server "loopback": schema "Does not exist" is not present on foreign server "cdb_fs_loopback"
|
||||
## Registering a table: NULL schema fails
|
||||
ERROR: Schema name cannot be NULL
|
||||
## Registering a table: Invalid table fails
|
||||
ERROR: Could not import table "remote_schema.Does not exist" of server "loopback"
|
||||
## Registering a table: NULL table fails
|
||||
ERROR: Remote table name cannot be NULL
|
||||
## Registering a table: Invalid id fails
|
||||
ERROR: non integer id_column "Does not exist"
|
||||
## Registering a table: NULL id fails
|
||||
ERROR: non integer id_column "<NULL>"
|
||||
## Registering a table: Invalid geom_column fails
|
||||
ERROR: non geometry column "Does not exists"
|
||||
## Registering a table: NULL geom_column is OK: Reuses geom_mercator
|
||||
|
||||
t|remote_geom|cdb_fs_loopback.remote_geom|id|geom|geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
|
||||
## Registering a table: Invalid webmercator_column fails
|
||||
ERROR: non geometry column "Does not exists"
|
||||
## Registering a table: NULL webmercator_column is OK: Reuses geom
|
||||
|
||||
t|remote_geom|cdb_fs_loopback.remote_geom|id|geom|geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
|
||||
##Registering a table with extra columns show the correct information
|
||||
|
||||
t|remote_geom3|cdb_fs_loopback.remote_geom3|id|geom|geom_mercator|[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
|
||||
## Target conflict is handled nicely: Table
|
||||
CREATE TABLE
|
||||
ERROR: Could not import table "remote_geom" as "cdb_fs_loopback.localtable" already exists
|
||||
## Target conflict is handled nicely: View
|
||||
CREATE VIEW
|
||||
ERROR: Could not import table "remote_geom" as "cdb_fs_loopback.localtable2" already exists
|
||||
DROP VIEW
|
||||
DROP TABLE
|
||||
## Registering tables does not work without permissions
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
## Normal users can not write in the import schema
|
||||
ERROR: permission denied for schema cdb_fs_loopback at character 14
|
||||
## Listing remote tables does not work without permissions
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
## Registering tables works with granted permissions
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
|
||||
## Listing remote tables works with granted permissions
|
||||
t|remote_geom|cdb_fs_loopback.localtable|id|geom|geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
t|remote_geom2|cdb_fs_loopback.different_name|cartodb_id|the_geom_webmercator|the_geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "cartodb_id", "Type" : "bigint"}, {"Name" : "the_geom", "Type" : "GEOMETRY,4326"}, {"Name" : "the_geom_webmercator", "Type" : "GEOMETRY,3857"}]
|
||||
f|remote_geom3|||||[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
f|remote_other|||||[{"Name" : "field", "Type" : "text"}, {"Name" : "field2", "Type" : "text"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
## Selecting from a registered table with granted permissions works
|
||||
1|POINT(1 1)
|
||||
2|POINT(2 2)
|
||||
## Selecting from a registered table without permissions does not work
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester2".
|
||||
CREATE FUNCTION
|
||||
t
|
||||
DROP FUNCTION
|
||||
## Deleting a registered table without permissions does not work
|
||||
ERROR: Not enough permissions to access the server "loopback"
|
||||
## Only the owner can grant permissions over the server
|
||||
ERROR: You do not have rights to grant access on "loopback"
|
||||
## Everything works for a different user when granted permissions
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester2".
|
||||
t|remote_geom|cdb_fs_loopback.localtable|id|geom|geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
t|remote_geom2|cdb_fs_loopback.different_name|cartodb_id|the_geom_webmercator|the_geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "cartodb_id", "Type" : "bigint"}, {"Name" : "the_geom", "Type" : "GEOMETRY,4326"}, {"Name" : "the_geom_webmercator", "Type" : "GEOMETRY,3857"}]
|
||||
f|remote_geom3|||||[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
f|remote_other|||||[{"Name" : "field", "Type" : "text"}, {"Name" : "field2", "Type" : "text"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
1|POINT(1 1)
|
||||
2|POINT(2 2)
|
||||
## A different user can unregister a table
|
||||
NOTICE: drop cascades to view cdb_fs_loopback.localtable
|
||||
|
||||
f|remote_geom|||||[{"Name" : "another_field", "Type" : "text"}, {"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "id", "Type" : "integer"}]
|
||||
t|remote_geom2|cdb_fs_loopback.different_name|cartodb_id|the_geom_webmercator|the_geom|[{"Name" : "another_field", "Type" : "text"}, {"Name" : "cartodb_id", "Type" : "bigint"}, {"Name" : "the_geom", "Type" : "GEOMETRY,4326"}, {"Name" : "the_geom_webmercator", "Type" : "GEOMETRY,3857"}]
|
||||
f|remote_geom3|||||[{"Name" : "geom", "Type" : "GEOMETRY,4326"}, {"Name" : "geom_mercator", "Type" : "GEOMETRY,3857"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
f|remote_other|||||[{"Name" : "field", "Type" : "text"}, {"Name" : "field2", "Type" : "text"}, {"Name" : "id", "Type" : "bigint"}]
|
||||
## Only the owner can revoke permissions over the server
|
||||
ERROR: You do not have rights to revoke access on "loopback"
|
||||
D1|
|
||||
69
test/CDB_FederatedServer_expect
Normal file
69
test/CDB_FederatedServer_expect
Normal file
@@ -0,0 +1,69 @@
|
||||
## List empty servers shows nothing
|
||||
## List non-existent server shows nothing
|
||||
## Create and list a server works
|
||||
1.3|
|
||||
1.4|(myRemote,postgres_fdw,localhost,5432,,read-only,fdw_user)
|
||||
## Create and list a second server works
|
||||
2.1|
|
||||
2.2|(myRemote,postgres_fdw,localhost,5432,,read-only,fdw_user)
|
||||
2.2|(myRemote2,postgres_fdw,localhost,5432,fdw_target,read-only,fdw_user)
|
||||
## List server by name works
|
||||
2.3|(myRemote,postgres_fdw,localhost,5432,,read-only,fdw_user)
|
||||
## Re-register a second server works
|
||||
3.1|
|
||||
3.2|(myRemote,postgres_fdw,localhost,5432,,read-only,fdw_user)
|
||||
3.2|(myRemote2,postgres_fdw,localhost,5432,fdw_target,read-only,other_remote_user)
|
||||
## Unregister server 1 works
|
||||
4.1|
|
||||
4.2|(myRemote2,postgres_fdw,localhost,5432,fdw_target,read-only,other_remote_user)
|
||||
## Unregistering a server that does not exist fails
|
||||
ERROR: Server "doesNotExist" does not exist
|
||||
## Unregister the second server works
|
||||
6.1|
|
||||
## Create a server with NULL name fails
|
||||
ERROR: Server name cannot be NULL
|
||||
## Create a server with NULL config fails
|
||||
7.01|
|
||||
## Create a server with empty config fails
|
||||
ERROR: Server information is mandatory
|
||||
## Create a server without credentials fails
|
||||
ERROR: Credentials are mandatory
|
||||
## Create a server with empty credentials works
|
||||
7.3|
|
||||
7.4|(empty,postgres_fdw,localhost,5432,fdw_target,read-only,)
|
||||
7.5|
|
||||
## Create a server without options fails
|
||||
ERROR: Server information is mandatory
|
||||
## Create a server with special characters works
|
||||
8.1|
|
||||
8.2|("myRemote"" or'not",postgres_fdw,localhost,5432,"fdw target",read-only,"fdw user")
|
||||
8.3|
|
||||
9.1|
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
## All users are able to list servers
|
||||
9.2|(myRemote3,postgres_fdw,localhost,5432,,read-only,)
|
||||
## Only superadmins can create servers
|
||||
ERROR: Could not create server myRemote4: permission denied for foreign-data wrapper postgres_fdw
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
## Granting access to a user works
|
||||
9.5|
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
9.55|(myRemote3,postgres_fdw,localhost,5432,,read-only,fdw_user)
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
ERROR: Server "does not exist" does not exist
|
||||
ERROR: Could not grant access on "myRemote3" to "does not exist": role "does not exist" does not exist
|
||||
## Granting access again raises a notice
|
||||
NOTICE: role "cdb_fs_tester" is already a member of role "cdb_fs_role_95b63382aabca4433e7bd9cba6c30368"
|
||||
9.8|
|
||||
## Revoking access to a user works
|
||||
9.9|
|
||||
9.10|
|
||||
## Unregistering a server with active grants works
|
||||
9.11|
|
||||
## A user with granted access can not drop a server
|
||||
10.1|
|
||||
10.2|
|
||||
You are now connected to database "contrib_regression" as user "cdb_fs_tester".
|
||||
ERROR: Not enough permissions to drop the server "myRemote4"
|
||||
You are now connected to database "contrib_regression" as user "postgres".
|
||||
10.4|
|
||||
@@ -51,7 +51,7 @@ UPDATE test_sync_dest SET the_geom = cartodb.CDB_LatLng(lat, lon); -- A "gecodin
|
||||
SET client_min_messages TO notice;
|
||||
SELECT cartodb.CDB_SyncTable('test_sync_source', 'public', 'test_sync_dest', '{the_geom, the_geom_webmercator}');
|
||||
SELECT * FROM test_sync_source ORDER BY cartodb_id;
|
||||
SELECT * FROM test_sync_dest ORDER BY cartodb_id;
|
||||
SELECT cartodb_id, the_geom, lat, lon, name FROM test_sync_dest ORDER BY cartodb_id;
|
||||
|
||||
\echo 'It will work with schemas that need quoting'
|
||||
\set QUIET on
|
||||
|
||||
@@ -54,10 +54,10 @@ NOTICE: MODIFIED 0 row(s)
|
||||
2|||2|2|bar
|
||||
4|||4|4|cantaloupe
|
||||
5|||5|5|sandia
|
||||
1|0101000020E6100000000000000000F03F000000000000F03F|0101000020110F0000DB0B4ADA772DFB402B432E49D22DFB40|1|1|foo
|
||||
2|0101000020E610000000000000000000400000000000000040|0101000020110F00003C0C4ADA772D0B4177F404ABE12E0B41|2|2|bar
|
||||
4|0101000020E610000000000000000010400000000000001040|0101000020110F00003C0C4ADA772D1B4160AB497020331B41|4|4|cantaloupe
|
||||
5|0101000020E610000000000000000014400000000000001440|0101000020110F000099476EE86AFC20413E7EB983F2012141|5|5|sandia
|
||||
1|0101000020E6100000000000000000F03F000000000000F03F|1|1|foo
|
||||
2|0101000020E610000000000000000000400000000000000040|2|2|bar
|
||||
4|0101000020E610000000000000000010400000000000001040|4|4|cantaloupe
|
||||
5|0101000020E610000000000000000014400000000000001440|5|5|sandia
|
||||
It will work with schemas that need quoting
|
||||
|
||||
INSERT 0 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
postgres
|
||||
@@PGUSER@@
|
||||
|
||||
fulano
|
||||
fulanito
|
||||
|
||||
@@ -598,68 +598,6 @@ test_extension|public|"local-table-with-dashes"'
|
||||
sql postgres "DROP FOREIGN TABLE IF EXISTS test_fdw.cdb_tablemetadata;"
|
||||
sql postgres "SELECT cartodb.CDB_Get_Foreign_Updated_At('test_fdw.foo') IS NULL" should 't'
|
||||
|
||||
|
||||
# Check user-defined FDW's
|
||||
# Set up a user foreign server
|
||||
read -d '' ufdw_config <<- EOF
|
||||
{
|
||||
"server": {
|
||||
"extensions": "postgis",
|
||||
"dbname": "fdw_target",
|
||||
"host": "localhost",
|
||||
"port": ${PGPORT:-5432}
|
||||
},
|
||||
"user_mapping": {
|
||||
"user": "fdw_user",
|
||||
"password": "foobarino"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
sql postgres "SELECT cartodb._CDB_SetUp_User_PG_FDW_Server('user-defined-test', '$ufdw_config');"
|
||||
|
||||
# Grant a user access to that FDW, and to grant to others
|
||||
sql postgres 'GRANT "cdb_fdw_user-defined-test" TO cdb_testmember_1 WITH ADMIN OPTION;'
|
||||
|
||||
# Set up a user foreign table
|
||||
sql cdb_testmember_1 "SELECT cartodb.CDB_SetUp_User_PG_FDW_Table('user-defined-test', 'test_fdw', 'foo');"
|
||||
|
||||
# Check that the table can be accessed by the owner/creator
|
||||
sql cdb_testmember_1 'SELECT * from "cdb_fdw_user-defined-test".foo;'
|
||||
sql cdb_testmember_1 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' should 42
|
||||
|
||||
# Check that a role with no permissions cannot use the FDW to access a remote table
|
||||
sql cdb_testmember_2 'IMPORT FOREIGN SCHEMA test_fdw LIMIT TO (foo) FROM SERVER "cdb_fdw_user-defined-test" INTO public' fails
|
||||
|
||||
# Check that the table can be accessed by some other user by granting the role
|
||||
sql cdb_testmember_2 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' fails
|
||||
sql cdb_testmember_1 'GRANT "cdb_fdw_user-defined-test" TO cdb_testmember_2;'
|
||||
sql cdb_testmember_2 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' should 42
|
||||
sql cdb_testmember_1 'REVOKE "cdb_fdw_user-defined-test" FROM cdb_testmember_2;'
|
||||
|
||||
# Check that the table can be accessed by org members
|
||||
sql cdb_testmember_2 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' fails
|
||||
sql cdb_testmember_1 "SELECT cartodb.CDB_Organization_Grant_Role('cdb_fdw_user-defined-test');"
|
||||
sql cdb_testmember_2 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' should 42
|
||||
sql cdb_testmember_1 "SELECT cartodb.CDB_Organization_Revoke_Role('cdb_fdw_user-defined-test');"
|
||||
|
||||
# By default publicuser cannot access the FDW
|
||||
sql publicuser 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' fails
|
||||
sql cdb_testmember_1 'GRANT "cdb_fdw_user-defined-test" TO publicuser;' # but can be granted
|
||||
sql publicuser 'SELECT a from "cdb_fdw_user-defined-test".foo LIMIT 1;' should 42
|
||||
sql cdb_testmember_1 'REVOKE "cdb_fdw_user-defined-test" FROM publicuser;'
|
||||
|
||||
# If there are dependent objects, we cannot drop the foreign server
|
||||
sql postgres "SELECT cartodb._CDB_Drop_User_PG_FDW_Server('user-defined-test')" fails
|
||||
sql cdb_testmember_1 'DROP FOREIGN TABLE "cdb_fdw_user-defined-test".foo;'
|
||||
sql postgres "SELECT cartodb._CDB_Drop_User_PG_FDW_Server('user-defined-test')"
|
||||
|
||||
# But if there are, we can set the force flag to true to drop everything (defaults to false)
|
||||
sql postgres "SELECT cartodb._CDB_SetUp_User_PG_FDW_Server('another_user_defined_test', '$ufdw_config');"
|
||||
sql postgres 'GRANT cdb_fdw_another_user_defined_test TO cdb_testmember_1 WITH ADMIN OPTION;'
|
||||
sql cdb_testmember_1 "SELECT cartodb.CDB_SetUp_User_PG_FDW_Table('another_user_defined_test', 'test_fdw', 'foo');"
|
||||
sql postgres "SELECT cartodb._CDB_Drop_User_PG_FDW_Server('another_user_defined_test', /* force = */ true)"
|
||||
|
||||
|
||||
# Teardown
|
||||
DATABASE=fdw_target sql postgres 'REVOKE USAGE ON SCHEMA test_fdw FROM fdw_user;'
|
||||
DATABASE=fdw_target sql postgres 'REVOKE SELECT ON test_fdw.foo FROM fdw_user;'
|
||||
|
||||
Reference in New Issue
Block a user