Fix many tests and handle ownership issues involved

with Cartodbfy being invoked by schema triggers. Some
issues with regclass interpretation in tests still remain.
Some issues with slightly different behavior to old version
remain. Some issues with error messages / notification messages
changing a little still remain.
This commit is contained in:
Paul Ramsey 2015-08-13 15:59:45 -07:00
parent a5321ec7a5
commit d268cd07cb
7 changed files with 68 additions and 31 deletions

View File

@ -973,6 +973,15 @@ BEGIN
sql := Format('DROP TABLE %s', reloid::text); sql := Format('DROP TABLE %s', reloid::text);
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table'); PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
-- If the table is being created by a SECURITY DEFINER function
-- make sure the user is set back to the user who is connected
IF current_user != session_user THEN
sql := Format('ALTER TABLE IF EXISTS %s OWNER TO %s', copyname, session_user);
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
sql := Format('ALTER SEQUENCE IF EXISTS %s OWNER TO %s', destseq, session_user);
PERFORM _CDB_SQL(sql, '_CDB_Rewrite_Table');
END IF;
-- If we used a temporary destination table -- If we used a temporary destination table
-- we can now rename it into place -- we can now rename it into place
IF destschema = relschema THEN IF destschema = relschema THEN

View File

@ -4,17 +4,23 @@ CREATE OR REPLACE FUNCTION cartodb.cdb_handle_create_table ()
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$ RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE DECLARE
event_info RECORD; event_info RECORD;
rel_namespace TEXT; rel RECORD;
newtable REGCLASS;
BEGIN BEGIN
event_info := schema_triggers.get_relation_create_eventinfo(); event_info := schema_triggers.get_relation_create_eventinfo();
-- We're only interested in real relations -- We're only interested in real relations
IF (event_info.new).relkind != 'r' THEN RETURN; END IF; IF (event_info.new).relkind != 'r' THEN RETURN; END IF;
SELECT nspname FROM pg_namespace WHERE oid=(event_info.new).relnamespace INTO rel_namespace; SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Relation % of kind % created in table % namespace % (oid %)', RAISE DEBUG 'Relation % of kind % created in table % namespace % (oid %)',
event_info.relation, (event_info.new).relkind, (event_info.new).relname::TEXT, rel_namespace, (event_info.new).relnamespace; event_info.relation, rel.relkind, rel.relname, rel.nspname, rel.relnamespace;
-- We don't want to react to alters triggered by superuser, -- We don't want to react to alters triggered by superuser,
IF current_setting('is_superuser') = 'on' THEN IF current_setting('is_superuser') = 'on' THEN
@ -25,15 +31,17 @@ BEGIN
PERFORM cartodb.cdb_disable_ddl_hooks(); PERFORM cartodb.cdb_disable_ddl_hooks();
-- CDB_CartodbfyTable must not create tables, or infinite loop will happen -- CDB_CartodbfyTable must not create tables, or infinite loop will happen
PERFORM cartodb.CDB_CartodbfyTable(rel_namespace, event_info.relation); PERFORM cartodb.CDB_CartodbfyTable(rel.nspname, event_info.relation);
PERFORM cartodb.cdb_enable_ddl_hooks(); PERFORM cartodb.cdb_enable_ddl_hooks();
RAISE DEBUG 'Inserting into cartodb.CDB_TableMetadata'; RAISE DEBUG 'Inserting into cartodb.CDB_TableMetadata';
newtable := Format('%s.%s', rel.nspname, rel.relname)::regclass;
-- Add entry to CDB_TableMetadata (should CartodbfyTable do this?) -- Add entry to CDB_TableMetadata (should CartodbfyTable do this?)
INSERT INTO cartodb.CDB_TableMetadata(tabname, updated_at) INSERT INTO cartodb.CDB_TableMetadata(tabname, updated_at)
VALUES (event_info.relation, now()); VALUES (newtable, now());
END; $$; END; $$;
-- } -- }
@ -66,14 +74,19 @@ RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE DECLARE
event_info RECORD; event_info RECORD;
rel RECORD; rel RECORD;
rel_namespace TEXT; newtable REGCLASS;
BEGIN BEGIN
event_info := schema_triggers.get_column_alter_eventinfo(); event_info := schema_triggers.get_column_alter_eventinfo();
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel; SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Column % altered by % (superuser? %) in relation % of kind %', RAISE DEBUG 'Column % altered by % (superuser? %) in relation % of kind %',
(event_info.old).attname, current_user, current_setting('is_superuser'), event_info.relation::regclass, rel.relkind; (event_info.old).attname, current_user, current_setting('is_superuser'), rel.relname, rel.relkind;
-- We're only interested in real relations -- We're only interested in real relations
IF rel.relkind != 'r' THEN RETURN; END IF; IF rel.relkind != 'r' THEN RETURN; END IF;
@ -84,17 +97,17 @@ BEGIN
RETURN; RETURN;
END IF; END IF;
SELECT nspname FROM pg_namespace WHERE oid = rel.relnamespace INTO rel_namespace;
PERFORM cartodb.cdb_disable_ddl_hooks(); PERFORM cartodb.cdb_disable_ddl_hooks();
PERFORM cartodb.CDB_CartodbfyTable(rel_namespace, event_info.relation); PERFORM cartodb.CDB_CartodbfyTable(rel.nspname, event_info.relation);
PERFORM cartodb.cdb_enable_ddl_hooks(); PERFORM cartodb.cdb_enable_ddl_hooks();
newtable := Format('%s.%s', rel.nspname, rel.relname)::regclass;
-- update CDB_TableMetadata.updated_at (should invalidate varnish) -- update CDB_TableMetadata.updated_at (should invalidate varnish)
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW() UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW()
WHERE tabname = event_info.relation; WHERE tabname = newtable;
END; $$; END; $$;
-- } -- }
@ -106,14 +119,19 @@ RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
DECLARE DECLARE
event_info RECORD; event_info RECORD;
rel RECORD; rel RECORD;
rel_namespace TEXT; newtable REGCLASS;
BEGIN BEGIN
event_info := schema_triggers.get_column_drop_eventinfo(); event_info := schema_triggers.get_column_drop_eventinfo();
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel; SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Column % drop by % (superuser? %) in relation % of kind %', RAISE DEBUG 'Column % drop by % (superuser? %) in relation % of kind %',
(event_info.old).attname, current_user, current_setting('is_superuser'), event_info.relation::regclass, rel.relkind; (event_info.old).attname, current_user, current_setting('is_superuser'), rel.relname, rel.relkind;
-- We're only interested in real relations -- We're only interested in real relations
IF rel.relkind != 'r' THEN RETURN; END IF; IF rel.relkind != 'r' THEN RETURN; END IF;
@ -124,17 +142,18 @@ BEGIN
RETURN; RETURN;
END IF; END IF;
SELECT nspname FROM pg_namespace WHERE oid = rel.relnamespace INTO rel_namespace;
PERFORM cartodb.cdb_disable_ddl_hooks(); PERFORM cartodb.cdb_disable_ddl_hooks();
PERFORM cartodb.CDB_CartodbfyTable(rel_namespace, event_info.relation); PERFORM cartodb.CDB_CartodbfyTable(rel.nspname, event_info.relation);
PERFORM cartodb.cdb_enable_ddl_hooks(); PERFORM cartodb.cdb_enable_ddl_hooks();
newtable := Format('%s.%s', rel.nspname, rel.relname)::regclass;
-- update CDB_TableMetadata.updated_at (should invalidate varnish) -- update CDB_TableMetadata.updated_at (should invalidate varnish)
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW() UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW()
WHERE tabname = event_info.relation; WHERE tabname = newtable;
END; $$; END; $$;
-- } -- }
@ -149,10 +168,15 @@ DECLARE
BEGIN BEGIN
event_info := schema_triggers.get_column_add_eventinfo(); event_info := schema_triggers.get_column_add_eventinfo();
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel; SELECT c.relname, c.relnamespace, c.relkind, n.nspname
FROM pg_class c
JOIN pg_namespace n
ON c.relnamespace = n.oid
WHERE c.oid = event_info.relation
INTO rel;
RAISE DEBUG 'Column % added by % (superuser? %) in relation % of kind %', RAISE DEBUG 'Column % added by % (superuser? %) in relation % of kind %',
(event_info.new).attname, current_user, current_setting('is_superuser'), event_info.relation::regclass, rel.relkind; (event_info.new).attname, current_user, current_setting('is_superuser'), rel.relname, rel.relkind;
-- We're only interested in real relations -- We're only interested in real relations
IF rel.relkind != 'r' THEN RETURN; END IF; IF rel.relkind != 'r' THEN RETURN; END IF;

View File

@ -10,6 +10,7 @@ create schema c;
SELECT CDB_SetUserQuotaInBytes('c', 0); SELECT CDB_SetUserQuotaInBytes('c', 0);
DROP USER IF EXISTS cartodb_postgresql_unpriv_user;
CREATE USER cartodb_postgresql_unpriv_user; CREATE USER cartodb_postgresql_unpriv_user;
GRANT ALL ON SCHEMA c to cartodb_postgresql_unpriv_user; GRANT ALL ON SCHEMA c to cartodb_postgresql_unpriv_user;
SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user'; SET SESSION AUTHORIZATION 'cartodb_postgresql_unpriv_user';

View File

@ -12,6 +12,7 @@ DECLARE
tmp INTEGER; tmp INTEGER;
ogc_geom geometry_columns; -- old the_geom record in geometry_columns ogc_geom geometry_columns; -- old the_geom record in geometry_columns
ogc_merc geometry_columns; -- old the_geom_webmercator record in geometry_columns ogc_merc geometry_columns; -- old the_geom_webmercator record in geometry_columns
tabtext TEXT;
BEGIN BEGIN
-- Save current constraints on geometry columns, if any -- Save current constraints on geometry columns, if any
@ -30,7 +31,10 @@ BEGIN
END IF; END IF;
END LOOP; END LOOP;
tabtext := Format('%s.%s','public',tabname);
RAISE NOTICE 'CARTODBFYING % !!!!', tabtext;
PERFORM CDB_CartodbfyTable('public', tabname); PERFORM CDB_CartodbfyTable('public', tabname);
tabname := tabtext::regclass;
sql := 'INSERT INTO ' || tabname::text || '(the_geom) values ( CDB_LatLng(2,1) ) RETURNING cartodb_id'; sql := 'INSERT INTO ' || tabname::text || '(the_geom) values ( CDB_LatLng(2,1) ) RETURNING cartodb_id';
EXECUTE sql INTO STRICT id; EXECUTE sql INTO STRICT id;
@ -121,9 +125,8 @@ $$
LANGUAGE 'plpgsql'; LANGUAGE 'plpgsql';
-- table with single non-geometrical column -- table with single non-geometrical column
CREATE TABLE t AS SELECT 1::int as a;
SELECT CDB_CartodbfyTable('public', 't'); -- should fail
SELECT CDB_SetUserQuotaInBytes(0); -- Set user quota to infinite SELECT CDB_SetUserQuotaInBytes(0); -- Set user quota to infinite
CREATE TABLE t AS SELECT 1::int as a;
SELECT CDB_CartodbfyTableCheck('t', 'single non-geometrical column'); SELECT CDB_CartodbfyTableCheck('t', 'single non-geometrical column');
DROP TABLE t; DROP TABLE t;

View File

@ -7,16 +7,16 @@ CREATE TABLE big(a int);
CREATE TRIGGER test_quota BEFORE UPDATE OR INSERT ON big CREATE TRIGGER test_quota BEFORE UPDATE OR INSERT ON big
EXECUTE PROCEDURE CDB_CheckQuota(1, 1, 'public'); EXECUTE PROCEDURE CDB_CheckQuota(1, 1, 'public');
INSERT INTO big VALUES (1); -- allowed, check runs before INSERT INTO big VALUES (1); -- allowed, check runs before
INSERT INTO big VALUES (1); -- disallowed, quota exceeds before INSERT INTO big VALUES (2); -- disallowed, quota exceeds before
SELECT CDB_SetUserQuotaInBytes(0); SELECT CDB_SetUserQuotaInBytes(0);
SELECT CDB_CartodbfyTable('big'); SELECT CDB_CartodbfyTable('big');
INSERT INTO big SELECT generate_series(1,2048); INSERT INTO big SELECT generate_series(2049,4096);
INSERT INTO big SELECT generate_series(1,2048); INSERT INTO big SELECT generate_series(4097,6144);
INSERT INTO big SELECT generate_series(1,2048); INSERT INTO big SELECT generate_series(6145,8192);
SELECT CDB_SetUserQuotaInBytes(2); SELECT CDB_SetUserQuotaInBytes(2);
INSERT INTO big VALUES (1); INSERT INTO big VALUES (8193);
SELECT CDB_SetUserQuotaInBytes(0); SELECT CDB_SetUserQuotaInBytes(0);
INSERT INTO big VALUES (1); INSERT INTO big VALUES (8194);
DROP TABLE big; DROP TABLE big;
set client_min_messages to NOTICE; set client_min_messages to NOTICE;
DROP FUNCTION _CDB_UserQuotaInBytes(); DROP FUNCTION _CDB_UserQuotaInBytes();

View File

@ -9,7 +9,7 @@ INSERT 0 2048
INSERT 0 2048 INSERT 0 2048
INSERT 0 2048 INSERT 0 2048
2 2
ERROR: Quota exceeded by 519.998046875KB ERROR: Quota exceeded by 443.998046875KB
0 0
INSERT 0 1 INSERT 0 1
DROP TABLE DROP TABLE