Compare commits

...

42 Commits

Author SHA1 Message Date
Alejandro Martínez
33b4f3718b Release 0.14.1 2016-03-07 12:05:22 +01:00
Alejandro Martínez
2e186c8565 Merge pull request #204 from CartoDB/fully-qualified-invalidations
Fully qualify invalidation calls (Fixes #198)
2016-03-07 11:45:01 +01:00
Alejandro Martínez
90c16fdb13 Fully qualify invalidations 2016-03-02 16:22:22 +01:00
Rafa de la Torre
54973c01f2 Add new version 0.14.0 with FDW support 2016-02-12 16:37:59 +01:00
Rafa de la Torre
eb4564ecee Merge pull request #199 from CartoDB/fdw-function-calls-with-schema
Fdw function calls with schema
2016-02-12 16:31:58 +01:00
Rafa de la Torre
abdc39f122 Merge pull request #200 from CartoDB/fdw-cdb_tablemetadata_text
Add CDB_TableMetadata_Text view as a proxy to access FDW tablemetadata
2016-02-12 14:47:05 +01:00
Rafa de la Torre
d2450ff361 Fix small typo in makefile 2016-02-12 11:34:04 +01:00
Rafa de la Torre
a0fe55bd5d Add a small bit of func doc about the quoting 2016-02-12 11:27:28 +01:00
Alejandro Martínez
56fed12392 Add CDB_TableMetadata_Text view as a proxy to access FDW tablemetadata 2016-02-11 19:16:00 +01:00
Rafa de la Torre
2f26b44142 tDo not quote dbname identifier
Turns out that for caching it is our standard not to have the dbname
quoted.
2016-02-11 16:10:27 +01:00
Rafa de la Torre
9596e8d9bc A couple checks for quoted idents in CDB_Last_Updated_Time 2016-02-10 19:10:57 +01:00
Rafa de la Torre
06036e2fe8 Quote identifiers returned by CDB_QueryTables_Updated_At 2016-02-10 18:58:01 +01:00
Rafa de la Torre
e870cf96e0 Merge pull request #196 from CartoDB/fdw-query-tables-updated-at
Fdw query tables updated at
2016-02-10 09:30:47 +01:00
Rafa de la Torre
2bce771488 Add some tests
Tests for:
* CDB_QueryTables_Updated_At
* CDB_Last_Updated_Time
2016-02-09 19:24:08 +01:00
Rafa de la Torre
cd4ad29e39 Remove schema when selecting from CDB_TableMetadata
to ease testing. When creating CDB_TableMetadata it is always put in
cartodb when done from the extension, but for tests it is done in
public.
2016-02-09 18:49:20 +01:00
Rafa de la Torre
d59b826d37 Fix silly bug: ordering of functions 2016-02-09 17:11:16 +01:00
Rafa de la Torre
1c637f8689 Small fixes: qualify cartodb function calls 2016-02-09 16:38:11 +01:00
Rafa de la Torre
ecbdb4a430 Move fdw-aware functions to CDB_ForeignTable.sql 2016-02-09 13:40:18 +01:00
Rafa de la Torre
eb84dd04c9 Add func CDB_Last_Updated_Time 2016-02-09 13:30:00 +01:00
Rafa de la Torre
276b5cf9ea Rename func to CDB_QueryTables_Updated_At
s/CDB_QueryTablesUpdatedAt/CDB_QueryTables_Updated_At and also add a bit
more inline doc.
2016-02-09 13:29:10 +01:00
Rafa de la Torre
ec34b8ee28 Minor changes: use plain SQL func 2016-02-08 19:29:14 +01:00
Rafa de la Torre
0f21db51b6 Simplify the code and get the updated_at 2016-02-08 19:29:14 +01:00
Rafa de la Torre
a074f4df5d Adapt CDB_QueryTablesUpdatedAt to _cdb_fqtn_from_text 2016-02-08 19:29:14 +01:00
Rafa de la Torre
1a12fd3b69 Make _cdb_fqtn_from_text return a table
with type instead of a record
2016-02-08 19:29:14 +01:00
Rafa de la Torre
78a75cf22d Implementation of _cdb_fqtn_from_text (WIP) 2016-02-08 19:29:14 +01:00
Rafa de la Torre
1e3c7ace99 Implementation of _cdb_dbname_of_foreign_table (WIP) 2016-02-08 19:29:14 +01:00
Rafa de la Torre
c210008184 Skeleton of a possible solution (WIP) 2016-02-08 19:29:14 +01:00
Rafa de la Torre
0c43fe2731 Define API of CDB_QueryTablesUpdatedAt 2016-02-08 19:29:14 +01:00
Alejandro Martínez
fdbad0f93c Fix specs on 9.3 2016-02-08 17:33:41 +01:00
Alejandro Martínez
131aee1503 Fully qualify function names 2016-02-08 16:35:26 +01:00
Alejandro Martínez
e858ddfa0b Add CDB_ForeignTable specs 2016-02-08 15:46:25 +01:00
Alejandro Martínez
edf79d9368 Add remote cdb_tablemetadata manually from public schema 2016-02-08 15:45:58 +01:00
Rafa de la Torre
c26ab0fdd1 Merge pull request #195 from CartoDB/fdw-rtorre
Fix small typos: s/name/fdw_name/
2016-02-05 13:18:24 +01:00
Rafa de la Torre
8dedd2b3f4 Fix small typos: s/name/fdw_name/ 2016-02-05 13:15:20 +01:00
Rafa de la Torre
11834dfdab Fix typo: missing semicolon 2016-02-05 10:44:55 +01:00
Alejandro Martínez
b957635e78 Add CDB_Get_Foreign_Updated_At function 2016-02-04 18:26:43 +01:00
Alejandro Martínez
a9b9f1ff6c Rename CDB_FDW_Create to CDB_FDW_Setup, formatting fixes 2016-02-04 12:06:22 +01:00
Alejandro Martínez
d7b560324a Add _Create_FDW function to create a FDW defined on the config by name 2016-02-03 18:07:23 +01:00
Alejandro Martínez
7b52058265 Add CDB_ForeignTable functions 2016-02-03 17:50:13 +01:00
Javier Goizueta
40a163f885 Release 0.13.1 2016-02-01 19:23:38 +01:00
Javier Goizueta
01d432c22c Merge pull request #193 from CartoDB/fix-multiline-fn
Fix function declaration for create_from_unpackaged.sh use
2016-02-01 19:16:37 +01:00
Javier Goizueta
5285943dbf Fix function declaration for create_from_unpackaged.sh use
The script create_from_unpackaged.sh does not support
function declarations where the signature (name and parameter list
of the function, including parentheses) is not on a single line.
2016-02-01 18:56:55 +01:00
7 changed files with 372 additions and 17 deletions

View File

@@ -1,7 +1,7 @@
# cartodb/Makefile
EXTENSION = cartodb
EXTVERSION = 0.13.0
EXTVERSION = 0.14.1
SED = sed
@@ -55,9 +55,12 @@ UPGRADABLE = \
0.11.2 \
0.11.3 \
0.11.4 \
0.11.5 \
0.12.0 \
0.13.0 \
0.11.5 \
0.12.0 \
0.13.0 \
0.13.1 \
0.14.0 \
0.14.1 \
$(EXTVERSION)dev \
$(EXTVERSION)next \
$(END)
@@ -91,7 +94,8 @@ $(EXTENSION)--$(EXTVERSION).sql: $(CDBSCRIPTS) cartodb_version.sql Makefile
echo '\echo Use "CREATE EXTENSION $(EXTENSION)" to load this file. \quit' > $@
cat $(CDBSCRIPTS) | \
$(SED) -e 's/public\./cartodb./g' \
-e 's/:DATABASE_USERNAME/cdb_org_admin/g' >> $@
-e 's/:DATABASE_USERNAME/cdb_org_admin/g' \
-e "s/''public''/''cartodb''/g" >> $@
echo "GRANT USAGE ON SCHEMA cartodb TO public;" >> $@
cat cartodb_version.sql >> $@

13
NEWS.md
View File

@@ -1,4 +1,17 @@
0.14.1 (2016-03-07)
-------------------
* Fully qualify table names in cache cdb_invalidate_varnish calls [#198](https://github.com/CartoDB/cartodb-postgresql/issues/198)
0.14.0 (2016-02-14)
-------------------
* Add CDB_ForeignTable.sql to support FDW's [#199](https://github.com/CartoDB/cartodb-postgresql/pull/199)
0.13.1 (2016-02-01)
-------------------
* Fix migration fron unpackaged. [193](https://github.com/CartoDB/cartodb-postgresql/pull/193)
0.13.0 (2016-01-29)
-------------------
* Add CDB_CreateOverviews, CDB_DropOverviews and CDB_Overviews for vector overviews support. [185](https://github.com/CartoDB/cartodb-postgresql/pull/185)
* Convert some simple functions from plpgsql to sql. [188](https://github.com/CartoDB/cartodb-postgresql/pull/188)

View File

@@ -0,0 +1,199 @@
---------------------------
-- FDW MANAGEMENT FUNCTIONS
--
-- All the FDW settings are read from the `cdb_conf.fdws` entry json file.
---------------------------
CREATE OR REPLACE FUNCTION cartodb._CDB_Setup_FDW(fdw_name text, config json)
RETURNS void
AS $$
DECLARE
row record;
option record;
org_role text;
BEGIN
-- This function tries to be as idempotent as possible, by not creating anything more than once
-- (not even using IF NOT EXIST to avoid throwing warnings)
IF NOT EXISTS ( SELECT * FROM pg_extension WHERE extname = 'postgres_fdw') THEN
CREATE EXTENSION postgres_fdw;
END IF;
-- Create FDW first if it does not exist
IF NOT EXISTS ( SELECT * FROM pg_foreign_server WHERE srvname = fdw_name)
THEN
EXECUTE FORMAT('CREATE SERVER %I FOREIGN DATA WRAPPER postgres_fdw', fdw_name);
END IF;
-- Set FDW settings
FOR row IN SELECT p.key, p.value from lateral json_each_text(config->'server') p
LOOP
IF NOT EXISTS (WITH a AS (select split_part(unnest(srvoptions), '=', 1) as options from pg_foreign_server where srvname=fdw_name) SELECT * from a where options = row.key)
THEN
EXECUTE FORMAT('ALTER SERVER %I OPTIONS (ADD %I %L)', fdw_name, row.key, row.value);
ELSE
EXECUTE FORMAT('ALTER SERVER %I OPTIONS (SET %I %L)', fdw_name, row.key, row.value);
END IF;
END LOOP;
-- Create user mappings
FOR row IN SELECT p.key, p.value from lateral json_each(config->'users') p LOOP
-- Check if entry on pg_user_mappings exists
IF NOT EXISTS ( SELECT * FROM pg_user_mappings WHERE srvname = fdw_name AND usename = row.key ) THEN
EXECUTE FORMAT ('CREATE USER MAPPING FOR %I SERVER %I', row.key, fdw_name);
END IF;
-- Update user mapping settings
FOR option IN SELECT o.key, o.value from lateral json_each_text(row.value) o LOOP
IF NOT EXISTS (WITH a AS (select split_part(unnest(umoptions), '=', 1) as options from pg_user_mappings WHERE srvname = fdw_name AND usename = row.key) SELECT * from a where options = option.key) THEN
EXECUTE FORMAT('ALTER USER MAPPING FOR %I SERVER %I OPTIONS (ADD %I %L)', row.key, fdw_name, option.key, option.value);
ELSE
EXECUTE FORMAT('ALTER USER MAPPING FOR %I SERVER %I OPTIONS (SET %I %L)', row.key, fdw_name, option.key, option.value);
END IF;
END LOOP;
END LOOP;
-- Create schema if it does not exist.
IF NOT EXISTS ( SELECT * from pg_namespace WHERE nspname=fdw_name) THEN
EXECUTE FORMAT ('CREATE SCHEMA %I', fdw_name);
END IF;
-- Give the organization role usage permisions over the schema
SELECT cartodb.CDB_Organization_Member_Group_Role_Member_Name() INTO org_role;
EXECUTE FORMAT ('GRANT USAGE ON SCHEMA %I TO %I', fdw_name, org_role);
-- Bring here the remote cdb_tablemetadata
IF NOT EXISTS ( SELECT * FROM PG_CLASS WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname=fdw_name) and relname='cdb_tablemetadata') THEN
EXECUTE FORMAT ('CREATE FOREIGN TABLE %I.cdb_tablemetadata (tabname text, updated_at timestamp with time zone) SERVER %I OPTIONS (table_name ''cdb_tablemetadata_text'', schema_name ''public'', updatable ''false'')', fdw_name, fdw_name);
END IF;
EXECUTE FORMAT ('GRANT SELECT ON %I.cdb_tablemetadata TO %I', fdw_name, org_role);
END
$$
LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION cartodb._CDB_Setup_FDWS()
RETURNS VOID AS
$$
DECLARE
row record;
BEGIN
FOR row IN SELECT p.key, p.value from lateral json_each(cartodb.CDB_Conf_GetConf('fdws')) p LOOP
EXECUTE 'SELECT cartodb._CDB_Setup_FDW($1, $2)' USING row.key, row.value;
END LOOP;
END
$$
LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION cartodb._CDB_Setup_FDW(fdw_name text)
RETURNS void AS
$BODY$
DECLARE
config json;
BEGIN
SELECT p.value FROM LATERAL json_each(cartodb.CDB_Conf_GetConf('fdws')) p WHERE p.key = fdw_name INTO config;
EXECUTE 'SELECT cartodb._CDB_Setup_FDW($1, $2)' USING fdw_name, config;
END
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE OR REPLACE FUNCTION cartodb.CDB_Add_Remote_Table(source text, table_name text)
RETURNS void AS
$$
BEGIN
PERFORM cartodb._CDB_Setup_FDW(source);
EXECUTE FORMAT ('IMPORT FOREIGN SCHEMA %I LIMIT TO (%I) FROM SERVER %I INTO %I;', source, table_name, source, source);
--- Grant SELECT to publicuser
EXECUTE FORMAT ('GRANT SELECT ON %I.%I TO publicuser;', source, table_name);
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION cartodb.CDB_Get_Foreign_Updated_At(foreign_table regclass)
RETURNS timestamp with time zone AS
$$
DECLARE
remote_table_name text;
fdw_schema_name text;
time timestamp with time zone;
BEGIN
-- This will turn a local foreign table (referenced as regclass) to its fully qualified text remote table reference.
WITH a AS (SELECT ftoptions FROM pg_foreign_table WHERE ftrelid=foreign_table LIMIT 1),
b as (SELECT (pg_options_to_table(ftoptions)).* FROM a)
SELECT FORMAT('%I.%I', (SELECT option_value FROM b WHERE option_name='schema_name'), (SELECT option_value FROM b WHERE option_name='table_name'))
INTO remote_table_name;
-- We assume that the remote cdb_tablemetadata is called cdb_tablemetadata and is on the same schema as the queried table.
SELECT nspname FROM pg_class c, pg_namespace n WHERE c.oid=foreign_table AND c.relnamespace = n.oid INTO fdw_schema_name;
EXECUTE FORMAT('SELECT updated_at FROM %I.cdb_tablemetadata WHERE tabname=%L ORDER BY updated_at DESC LIMIT 1', fdw_schema_name, remote_table_name) INTO time;
RETURN time;
END
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION cartodb._cdb_dbname_of_foreign_table(reloid oid)
RETURNS TEXT AS $$
SELECT option_value FROM pg_options_to_table((
SELECT fs.srvoptions
FROM pg_foreign_table ft
LEFT JOIN pg_foreign_server fs ON ft.ftserver = fs.oid
WHERE ft.ftrelid = reloid
)) WHERE option_name='dbname';
$$ LANGUAGE SQL;
-- Return a set of (dbname, schema_name, table_name, updated_at)
-- It is aware of foreign tables
-- It assumes the local (schema_name, table_name) map to the remote ones with the same name
-- Note: dbname is never quoted whereas schema and table names are when needed.
CREATE OR REPLACE FUNCTION cartodb.CDB_QueryTables_Updated_At(query text)
RETURNS TABLE(dbname text, schema_name text, table_name text, updated_at timestamptz)
AS $$
WITH query_tables AS (
SELECT unnest(CDB_QueryTablesText(query)) schema_table_name
), query_tables_oid AS (
SELECT schema_table_name, schema_table_name::regclass::oid AS reloid
FROM query_tables
),
fqtn AS (
SELECT
(CASE WHEN c.relkind = 'f' THEN cartodb._cdb_dbname_of_foreign_table(query_tables_oid.reloid)
ELSE current_database()
END)::text AS dbname,
quote_ident(n.nspname::text) schema_name,
quote_ident(c.relname::text) table_name,
c.relkind,
query_tables_oid.reloid
FROM query_tables_oid, pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
WHERE c.oid = query_tables_oid.reloid
)
SELECT fqtn.dbname, fqtn.schema_name, fqtn.table_name,
(CASE WHEN relkind = 'f' THEN cartodb.CDB_Get_Foreign_Updated_At(reloid)
ELSE (SELECT md.updated_at FROM CDB_TableMetadata md WHERE md.tabname = reloid)
END) AS updated_at
FROM fqtn;
$$ LANGUAGE SQL;
-- Return the last updated time of a set of tables
-- It is aware of foreign tables
-- It assumes the local (schema_name, table_name) map to the remote ones with the same name
CREATE OR REPLACE FUNCTION cartodb.CDB_Last_Updated_Time(tables text[])
RETURNS timestamptz AS $$
WITH t AS (
SELECT unnest(tables) AS schema_table_name
), t_oid AS (
SELECT (t.schema_table_name)::regclass::oid as reloid FROM t
), t_updated_at AS (
SELECT
(CASE WHEN relkind = 'f' THEN cartodb.CDB_Get_Foreign_Updated_At(reloid)
ELSE (SELECT md.updated_at FROM CDB_TableMetadata md WHERE md.tabname = reloid)
END) AS updated_at
FROM t_oid
LEFT JOIN pg_catalog.pg_class c ON c.oid = reloid
) SELECT max(updated_at) FROM t_updated_at;
$$ LANGUAGE SQL;

View File

@@ -642,11 +642,7 @@ $$ LANGUAGE PLPGSQL;
-- created by the strategy must have the same columns
-- as the base table and in the same order.
-- Return value: Array with the names of the generated overview tables
CREATE OR REPLACE FUNCTION CDB_CreateOverviews(
reloid REGCLASS,
refscale_strategy regproc DEFAULT '_CDB_Feature_Density_Ref_Z_Strategy'::regproc,
reduce_strategy regproc DEFAULT '_CDB_GridCluster_Reduce_Strategy'::regproc
)
CREATE OR REPLACE FUNCTION CDB_CreateOverviews(reloid REGCLASS, refscale_strategy regproc DEFAULT '_CDB_Feature_Density_Ref_Z_Strategy'::regproc, reduce_strategy regproc DEFAULT '_CDB_GridCluster_Reduce_Strategy'::regproc)
RETURNS text[]
AS $$
DECLARE

View File

@@ -5,6 +5,11 @@ CREATE TABLE IF NOT EXISTS
updated_at timestamp with time zone not null default now()
);
CREATE OR REPLACE VIEW public.CDB_TableMetadata_Text AS
SELECT FORMAT('%I.%I', n.nspname::text, c.relname::text) tabname, updated_at
FROM public.CDB_TableMetadata, pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid;
-- No one can see this
-- Updates are only possible trough the security definer trigger
-- GRANT SELECT ON public.CDB_TableMetadata TO public;
@@ -61,9 +66,11 @@ CREATE OR REPLACE FUNCTION _CDB_TableMetadata_Updated()
RETURNS trigger AS
$$
DECLARE
tabname TEXT;
tabname regclass;
rec RECORD;
found BOOL;
schema_name TEXT;
table_name TEXT;
BEGIN
IF TG_OP = 'UPDATE' or TG_OP = 'INSERT' THEN
@@ -98,9 +105,10 @@ BEGIN
AND u.usesuper
ORDER BY n.nspname
LOOP
SELECT n.nspname, c.relname FROM pg_class c, pg_namespace n WHERE c.oid=tabname AND c.relnamespace = n.oid INTO schema_name, table_name;
EXECUTE 'SELECT ' || quote_ident(rec.nspname) || '.'
|| quote_ident(rec.proname)
|| '(' || quote_literal(tabname) || ')';
|| '(' || quote_literal(quote_ident(schema_name) || '.' || quote_ident(table_name)) || ')';
found := true;
EXIT;
END LOOP;
@@ -111,11 +119,11 @@ END;
$$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
DROP TRIGGER IF EXISTS table_modified ON CDB_TableMetadata;
DROP TRIGGER IF EXISTS table_modified ON public.CDB_TableMetadata;
-- NOTE: on DELETE we would be unable to convert the table
-- oid (regclass) to its name
CREATE TRIGGER table_modified AFTER INSERT OR UPDATE
ON CDB_TableMetadata FOR EACH ROW EXECUTE PROCEDURE
ON public.CDB_TableMetadata FOR EACH ROW EXECUTE PROCEDURE
_CDB_TableMetadata_Updated();

View File

@@ -0,0 +1 @@
../scripts-available/CDB_ForeignTable.sql

View File

@@ -172,8 +172,7 @@ function drop_raster_table() {
sql ${ROLE} "DROP TABLE ${ROLE}.${TABLENAME};"
}
function setup() {
function setup_database() {
${CMD} -c "CREATE DATABASE ${DATABASE}"
sql "CREATE SCHEMA cartodb;"
sql "GRANT USAGE ON SCHEMA cartodb TO public;"
@@ -184,7 +183,10 @@ function setup() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_Organizations.sql
# trick to allow forcing a schema when loading SQL files (see: http://bit.ly/1HeLnhL)
${CMD} -d ${DATABASE} -f test/extension/run_at_cartodb_schema.sql
}
function setup() {
setup_database
log_info "############################# SETUP #############################"
create_role_and_schema cdb_testmember_1
@@ -199,6 +201,10 @@ function setup() {
sql cdb_testmember_2 'SELECT * FROM cdb_testmember_2.bar;'
}
function tear_down_database() {
${CMD} -c "DROP DATABASE ${DATABASE}"
}
function tear_down() {
log_info "########################### USER TEAR DOWN ###########################"
sql cdb_testmember_1 "SELECT * FROM cartodb.CDB_Organization_Remove_Access_Permission('cdb_testmember_1', 'foo', 'cdb_testmember_2');"
@@ -219,9 +225,10 @@ function tear_down() {
sql 'DROP ROLE cdb_testmember_1;'
sql 'DROP ROLE cdb_testmember_2;'
${CMD} -c "DROP DATABASE ${DATABASE}"
tear_down_database
}
function run_tests() {
local FAILED_TESTS=()
@@ -343,6 +350,41 @@ function test_cdb_tablemetadatatouch_fails_from_user_without_permission() {
sql postgres "REVOKE ALL ON CDB_TableMetadata FROM cdb_testmember_1;"
}
function test_cdb_tablemetadatatouch_fully_qualifies_names() {
sql postgres "CREATE TABLE touch_invalidations (table_name text);"
sql postgres "create or replace function cartodb.cdb_invalidate_varnish(table_name text) returns void as \$\$ begin insert into touch_invalidations select table_name; end; \$\$ language 'plpgsql';"
#default schema
sql "CREATE TABLE touch_example (a int);"
sql postgres "SELECT CDB_TableMetadataTouch('touch_example');"
sql postgres "SELECT table_name FROM touch_invalidations" should "public.touch_example"
sql postgres "TRUNCATE TABLE touch_invalidations"
sql postgres "DROP TABLE touch_example"
#setup different schema
sql postgres "CREATE SCHEMA test_schema;"
sql postgres "CREATE TABLE test_schema.touch_example (a int);"
#different schema outside search_path
sql postgres "SELECT CDB_TableMetadataTouch('test_schema.touch_example');"
sql postgres "SELECT table_name FROM touch_invalidations" should "test_schema.touch_example"
sql postgres "TRUNCATE TABLE touch_invalidations"
#different schema in default search_path
sql postgres "SET search_path=test_schema,public,cartodb; SELECT CDB_TableMetadataTouch('test_schema.touch_example');"
sql postgres "SELECT table_name FROM touch_invalidations" should "test_schema.touch_example"
sql postgres "TRUNCATE TABLE touch_invalidations"
#teardown different schema
sql postgres 'DROP TABLE test_schema.touch_example;'
sql postgres 'DROP SCHEMA test_schema;'
sql postgres 'DROP FUNCTION cartodb.cdb_invalidate_varnish(table_name text);'
sql postgres 'DROP TABLE touch_invalidations'
}
function test_cdb_column_names() {
sql cdb_testmember_1 'CREATE TABLE cdb_testmember_1.table_cnames(c int, a int, r int, t int, o int);'
sql cdb_testmember_2 'CREATE TABLE cdb_testmember_2.table_cnames(d int, b int);'
@@ -429,6 +471,98 @@ function test_cdb_querytables_happy_cases() {
sql postgres 'DROP SCHEMA foo;'
}
function test_foreign_tables() {
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryStatements.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_QueryTables.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_TableMetadata.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_Conf.sql
${CMD} -d ${DATABASE} -f scripts-available/CDB_ForeignTable.sql
DATABASE=fdw_target setup_database
${CMD} -d fdw_target -f scripts-available/CDB_QueryStatements.sql
${CMD} -d fdw_target -f scripts-available/CDB_QueryTables.sql
${CMD} -d fdw_target -f scripts-available/CDB_TableMetadata.sql
DATABASE=fdw_target sql postgres 'CREATE SCHEMA test_fdw;'
DATABASE=fdw_target sql postgres 'CREATE TABLE test_fdw.foo (a int);'
DATABASE=fdw_target sql postgres 'INSERT INTO test_fdw.foo (a) values (42);'
DATABASE=fdw_target sql postgres 'CREATE TABLE test_fdw.foo2 (a int);'
DATABASE=fdw_target sql postgres 'INSERT INTO test_fdw.foo2 (a) values (42);'
DATABASE=fdw_target sql postgres "CREATE USER fdw_user WITH PASSWORD 'foobarino';"
DATABASE=fdw_target sql postgres 'GRANT USAGE ON SCHEMA test_fdw TO fdw_user;'
DATABASE=fdw_target sql postgres 'GRANT SELECT ON TABLE test_fdw.foo TO fdw_user;'
DATABASE=fdw_target sql postgres 'GRANT SELECT ON TABLE test_fdw.foo2 TO fdw_user;'
DATABASE=fdw_target sql postgres 'GRANT SELECT ON cdb_tablemetadata_text TO fdw_user;'
DATABASE=fdw_target sql postgres "SELECT cdb_tablemetadatatouch('test_fdw.foo'::regclass);"
DATABASE=fdw_target sql postgres "SELECT cdb_tablemetadatatouch('test_fdw.foo2'::regclass);"
sql postgres "SELECT cartodb.CDB_Conf_SetConf('fdws', '{\"test_fdw\": {\"server\": {\"host\": \"localhost\", \"dbname\": \"fdw_target\"},
\"users\": {\"public\": {\"user\": \"fdw_user\", \"password\": \"foobarino\"}}}}')"
sql postgres "SELECT cartodb._CDB_Setup_FDW('test_fdw')"
sql postgres "SHOW server_version_num"
if [ "$RESULT" -gt 90499 ]
then
sql postgres "SELECT cartodb.CDB_Add_Remote_Table('test_fdw', 'foo')"
sql postgres "SELECT * from test_fdw.foo;"
else
echo "NOTICE: PostgreSQL version is less than 9.5 ($RESULT). Skipping CDB_Add_Remote_Table."
sql postgres "CREATE FOREIGN TABLE test_fdw.foo (a int) SERVER test_fdw OPTIONS (table_name 'foo', schema_name 'test_fdw')"
fi
sql postgres "SELECT n.nspname,
c.relname,
s.srvname FROM pg_catalog.pg_foreign_table ft
INNER JOIN pg_catalog.pg_class c ON c.oid = ft.ftrelid
INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
INNER JOIN pg_catalog.pg_foreign_server s ON s.oid = ft.ftserver
ORDER BY 1, 2" should "test_fdw|cdb_tablemetadata|test_fdw
test_fdw|foo|test_fdw"
sql postgres "SELECT cartodb.CDB_Get_Foreign_Updated_At('test_fdw.foo'::regclass) < NOW()" should 't'
sql postgres "SELECT a from test_fdw.foo LIMIT 1;" should 42
# Check function CDB_QueryTables_Updated_At
sql postgres 'CREATE TABLE local (b int);'
sql postgres 'INSERT INTO local (b) VALUES (43);'
sql postgres "SELECT cdb_tablemetadatatouch('public.local'::regclass);"
local query='$query$ SELECT * FROM test_fdw.foo, local $query$::text'
sql postgres "SELECT dbname, schema_name, table_name FROM cartodb.CDB_QueryTables_Updated_At(${query}) ORDER BY dbname;" should 'fdw_target|test_fdw|foo
test_extension|public|local'
sql postgres "SELECT table_name FROM cartodb.CDB_QueryTables_Updated_At(${query}) order by updated_at;" should 'foo
local'
# Check function CDB_Last_Updated_Time
sql postgres "SELECT cartodb.CDB_Last_Updated_Time('{test_fdw.foo,public.local}'::text[]) < now()" should 't'
sql postgres "SELECT cartodb.CDB_Last_Updated_Time('{test_fdw.foo,public.local}'::text[]) > (now() - interval '1 minute')" should 't'
# Check we quote names on output as needed (as CDB_QueryTablesText does)
sql postgres 'CREATE TABLE "local-table-with-dashes" (c int)';
sql postgres 'INSERT INTO "local-table-with-dashes" (c) VALUES (44)';
sql postgres "SELECT cdb_tablemetadatatouch('public.local-table-with-dashes'::regclass);"
query='$query$ SELECT * FROM test_fdw.foo, local, public."local-table-with-dashes" $query$::text'
sql postgres "SELECT dbname, schema_name, table_name FROM cartodb.CDB_QueryTables_Updated_At(${query}) ORDER BY dbname, schema_name, table_name;" should 'fdw_target|test_fdw|foo
test_extension|public|local
test_extension|public|"local-table-with-dashes"'
# Check CDB_Last_Updated_Time supports quoted identifiers
sql postgres "SELECT cartodb.CDB_Last_Updated_Time(ARRAY['test_extension.public.\"local-table-with-dashes\"']::text[]) < now()" should 't'
sql postgres "SELECT cartodb.CDB_Last_Updated_Time(ARRAY['test_extension.public.\"local-table-with-dashes\"']::text[]) > (now() - interval '1 minute')" should 't'
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;'
DATABASE=fdw_target sql postgres 'REVOKE SELECT ON test_fdw.foo2 FROM fdw_user;'
DATABASE=fdw_target sql postgres 'REVOKE SELECT ON cdb_tablemetadata_text FROM fdw_user;'
DATABASE=fdw_target sql postgres 'DROP ROLE fdw_user;'
sql postgres "select pg_terminate_backend(pid) from pg_stat_activity where datname='fdw_target';"
DATABASE=fdw_target tear_down_database
}
#################################################### TESTS END HERE ####################################################
run_tests $@