Merge branch 'master' of https://github.com/CartoDB/cartodb-postgresql into CDB-3094
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
CREATE OR REPLACE FUNCTION _CDB_update_the_geom_webmercator()
|
||||
RETURNS trigger AS $$
|
||||
BEGIN
|
||||
NEW.the_geom_webmercator := CDB_TransformToWebmercator(NEW.the_geom);
|
||||
NEW.the_geom_webmercator := public.CDB_TransformToWebmercator(NEW.the_geom);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql VOLATILE;
|
||||
@@ -83,18 +83,27 @@ BEGIN
|
||||
RAISE NOTICE 'Column cartodb_id already exists';
|
||||
had_column := TRUE;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (cartodb_id): % (%)',
|
||||
reloid, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
|
||||
IF had_column THEN
|
||||
|
||||
SELECT pg_catalog.pg_get_serial_sequence(reloid::text, 'cartodb_id')
|
||||
AS seq INTO rec2;
|
||||
|
||||
-- Check data type is an integer
|
||||
SELECT t.typname, t.oid, a.attnotnull FROM pg_type t, pg_attribute a
|
||||
SELECT
|
||||
pg_catalog.pg_get_serial_sequence(reloid::text, 'cartodb_id') as seq,
|
||||
t.typname, t.oid, a.attnotnull FROM pg_type t, pg_attribute a
|
||||
WHERE a.atttypid = t.oid AND a.attrelid = reloid AND NOT a.attisdropped
|
||||
AND a.attname = 'cartodb_id'
|
||||
INTO STRICT rec;
|
||||
IF rec.oid NOT IN (20,21,23) THEN -- int2, int4, int8 {
|
||||
-- 20=int2, 21=int4, 23=int8
|
||||
IF rec.oid NOT IN (20,21,23) THEN -- {
|
||||
RAISE NOTICE 'Existing cartodb_id field is of invalid type % (need int2, int4 or int8), renaming', rec.typname;
|
||||
ELSIF rec.seq IS NULL THEN -- }{
|
||||
RAISE NOTICE 'Existing cartodb_id field does not have an associated sequence, renaming';
|
||||
ELSE -- }{
|
||||
sql := 'ALTER TABLE ' || reloid::text || ' ALTER COLUMN cartodb_id SET NOT NULL';
|
||||
IF NOT EXISTS ( SELECT c.conname FROM pg_constraint c, pg_attribute a
|
||||
@@ -102,7 +111,7 @@ BEGIN
|
||||
AND a.attrelid = reloid
|
||||
AND NOT a.attisdropped
|
||||
AND a.attname = 'cartodb_id'
|
||||
AND c.contype = 'u' ) -- unique
|
||||
AND c.contype IN ( 'u', 'p' ) ) -- unique or pkey
|
||||
THEN
|
||||
sql := sql || ', ADD unique(cartodb_id)';
|
||||
END IF;
|
||||
@@ -114,7 +123,8 @@ BEGIN
|
||||
WHEN unique_violation OR not_null_violation THEN
|
||||
RAISE NOTICE '%, renaming', SQLERRM;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (cartodb_id): % (%)',
|
||||
reloid, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
END IF; -- }
|
||||
|
||||
@@ -133,7 +143,8 @@ BEGIN
|
||||
i := i+1;
|
||||
CONTINUE rename_column;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (renaming cartodb_id): % (%)',
|
||||
reloid, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
EXIT rename_column;
|
||||
END LOOP; --}
|
||||
@@ -142,8 +153,51 @@ BEGIN
|
||||
END IF;
|
||||
END LOOP; -- }
|
||||
|
||||
-- Try to copy data from new name if possible
|
||||
IF new_name IS NOT NULL THEN
|
||||
RAISE NOTICE 'Trying to recover data from % column', new_name;
|
||||
BEGIN
|
||||
-- Copy existing values to new field
|
||||
-- NOTE: using ALTER is a workaround to a PostgreSQL bug and
|
||||
-- is also known to be faster for tables with many rows
|
||||
-- See http://www.postgresql.org/message-id/20140530143150.GA11051@localhost
|
||||
sql := 'ALTER TABLE ' || reloid::text
|
||||
|| ' ALTER cartodb_id TYPE int USING '
|
||||
|| new_name || '::int4';
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql;
|
||||
|
||||
-- Find max value
|
||||
sql := 'SELECT max(cartodb_id) FROM ' || reloid::text;
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql INTO rec;
|
||||
|
||||
-- Find sequence name
|
||||
SELECT pg_catalog.pg_get_serial_sequence(reloid::text, 'cartodb_id')
|
||||
AS seq INTO rec2;
|
||||
|
||||
-- Reset sequence name
|
||||
sql := 'ALTER SEQUENCE ' || rec2.seq::text
|
||||
|| ' RESTART WITH ' || rec.max + 1;
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql;
|
||||
|
||||
-- Drop old column (all went find if we got here)
|
||||
sql := 'ALTER TABLE ' || reloid::text || ' DROP ' || new_name;
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql;
|
||||
|
||||
EXCEPTION
|
||||
WHEN others THEN
|
||||
RAISE NOTICE 'Could not initialize cartodb_id with existing values: % (%)',
|
||||
SQLERRM, SQLSTATE;
|
||||
END;
|
||||
END IF;
|
||||
|
||||
-- We need created_at and updated_at
|
||||
FOR rec IN SELECT * FROM ( VALUES ('created_at'), ('updated_at') ) t(cname) LOOP --{
|
||||
FOR rec IN SELECT * FROM ( VALUES ('created_at'), ('updated_at') ) t(cname)
|
||||
LOOP --{
|
||||
new_name := null;
|
||||
<< column_setup >>
|
||||
LOOP --{
|
||||
had_column := FALSE;
|
||||
@@ -158,30 +212,39 @@ BEGIN
|
||||
RAISE NOTICE 'Column % already exists', rec.cname;
|
||||
had_column := TRUE;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (%): % (%)',
|
||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
|
||||
IF had_column THEN
|
||||
|
||||
-- Check data type is a TIMESTAMP WITH TIMEZONE
|
||||
SELECT t.typname, t.oid, a.attnotnull FROM pg_type t, pg_attribute a
|
||||
WHERE a.atttypid = t.oid AND a.attrelid = reloid AND NOT a.attisdropped
|
||||
AND a.attname = rec.cname
|
||||
WHERE a.atttypid = t.oid AND a.attrelid = reloid
|
||||
AND NOT a.attisdropped AND a.attname = rec.cname
|
||||
INTO STRICT rec2;
|
||||
IF rec2.oid NOT IN (1184) THEN -- timestamptz {
|
||||
RAISE NOTICE 'Existing % field is of invalid type % (need timestamptz), renaming', rec.cname, rec2.typname;
|
||||
RAISE NOTICE 'Existing % field is of invalid type % (need timestamptz), renaming', rec.
|
||||
cname, rec2.typname;
|
||||
ELSE -- }{
|
||||
sql := 'ALTER TABLE ' || reloid::text || ' ALTER ' || rec.cname
|
||||
|| ' SET NOT NULL, ALTER ' || rec.cname || ' SET DEFAULT now()';
|
||||
-- Ensure data type is a TIMESTAMP WITH TIMEZONE
|
||||
sql := 'ALTER TABLE ' || reloid::text
|
||||
|| ' ALTER ' || rec.cname
|
||||
|| ' SET NOT NULL,'
|
||||
|| ' ALTER ' || rec.cname
|
||||
|| ' SET DEFAULT now()';
|
||||
BEGIN
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql;
|
||||
EXIT column_setup;
|
||||
EXCEPTION
|
||||
WHEN not_null_violation THEN
|
||||
WHEN not_null_violation THEN -- failed not-null
|
||||
RAISE NOTICE '%, renaming', SQLERRM;
|
||||
WHEN cannot_coerce THEN -- failed cast
|
||||
RAISE NOTICE '%, renaming', SQLERRM;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (%): % (%)',
|
||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
END IF; -- }
|
||||
|
||||
@@ -199,7 +262,8 @@ BEGIN
|
||||
i := i+1;
|
||||
CONTINUE rename_column;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (renaming %): % (%)',
|
||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
EXIT rename_column;
|
||||
END LOOP; --}
|
||||
@@ -208,6 +272,32 @@ BEGIN
|
||||
END IF;
|
||||
END LOOP; -- }
|
||||
|
||||
-- Try to copy data from new name if possible
|
||||
IF new_name IS NOT NULL THEN -- {
|
||||
RAISE NOTICE 'Trying to recover data from % coumn', new_name;
|
||||
BEGIN
|
||||
-- Copy existing values to new field
|
||||
-- NOTE: using ALTER is a workaround to a PostgreSQL bug and
|
||||
-- is also known to be faster for tables with many rows
|
||||
-- See http://www.postgresql.org/message-id/20140530143150.GA11051@localhost
|
||||
sql := 'ALTER TABLE ' || reloid::text || ' ALTER ' || rec.cname
|
||||
|| ' TYPE TIMESTAMPTZ USING '
|
||||
|| new_name || '::timestamptz';
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql;
|
||||
|
||||
-- Drop old column (all went find if we got here)
|
||||
sql := 'ALTER TABLE ' || reloid::text || ' DROP ' || new_name;
|
||||
RAISE DEBUG 'Running %', sql;
|
||||
EXECUTE sql;
|
||||
|
||||
EXCEPTION
|
||||
WHEN others THEN
|
||||
RAISE NOTICE 'Could not initialize % with existing values: % (%)',
|
||||
rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
END IF; -- }
|
||||
|
||||
END LOOP; -- }
|
||||
|
||||
-- We need the_geom and the_geom_webmercator
|
||||
@@ -228,7 +318,8 @@ BEGIN
|
||||
exists_geom_cols := array_append(exists_geom_cols, true);
|
||||
RAISE NOTICE 'Column % already exists', rec.cname;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (%): % (%)',
|
||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
|
||||
<< column_fixup >>
|
||||
@@ -280,7 +371,8 @@ BEGIN
|
||||
EXECUTE sql;
|
||||
EXCEPTION
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (% index): % (%)',
|
||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
END IF; -- }
|
||||
|
||||
@@ -303,7 +395,8 @@ BEGIN
|
||||
i := i+1;
|
||||
CONTINUE rename_column;
|
||||
WHEN others THEN
|
||||
RAISE EXCEPTION 'Got % (%)', SQLERRM, SQLSTATE;
|
||||
RAISE EXCEPTION 'Cartodbfying % (rename %): % (%)',
|
||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||
END;
|
||||
EXIT rename_column;
|
||||
END LOOP; --}
|
||||
@@ -325,7 +418,7 @@ BEGIN
|
||||
-- do this only if the_geom was found (not created)
|
||||
-- _and_ the_geom_webmercator was NOT found.
|
||||
IF exists_geom_cols[1] AND NOT exists_geom_cols[2] THEN
|
||||
sql := 'UPDATE ' || reloid::text || ' SET the_geom_webmercator = CDB_TransformToWebmercator(the_geom) ';
|
||||
sql := 'UPDATE ' || reloid::text || ' SET the_geom_webmercator = public.CDB_TransformToWebmercator(the_geom) ';
|
||||
EXECUTE sql;
|
||||
END IF;
|
||||
|
||||
|
||||
@@ -11,6 +11,6 @@ AS $$
|
||||
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
-- This is a private function, so only the db owner need privileges
|
||||
REVOKE ALL ON FUNCTION CDB_ColumnNames(REGCLASS) FROM PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION CDB_ColumnNames(REGCLASS) TO ":DATABASE_USERNAME";
|
||||
-- This is to migrate from pre-0.2.0 version
|
||||
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36
|
||||
GRANT EXECUTE ON FUNCTION CDB_ColumnNames(REGCLASS) TO PUBLIC;
|
||||
|
||||
@@ -12,6 +12,6 @@ AS $$
|
||||
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
-- This is a private function, so only the db owner need privileges
|
||||
REVOKE ALL ON FUNCTION CDB_ColumnType(REGCLASS, TEXT) FROM PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION CDB_ColumnType(REGCLASS, TEXT) TO ":DATABASE_USERNAME";
|
||||
-- This is to migrate from pre-0.2.0 version
|
||||
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36
|
||||
GRANT EXECUTE ON FUNCTION CDB_ColumnType(REGCLASS, TEXT) TO public;
|
||||
|
||||
187
scripts-available/CDB_DDLTriggers.sql
Normal file
187
scripts-available/CDB_DDLTriggers.sql
Normal file
@@ -0,0 +1,187 @@
|
||||
-- Table creation
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_create_table ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_relation_create_eventinfo();
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF (event_info.new).relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
RAISE DEBUG 'Relation % of kind % created in namespace oid %',
|
||||
event_info.relation, (event_info.new).relkind, (event_info.new).relnamespace;
|
||||
|
||||
-- We don't want to react to alters triggered by superuser,
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
PERFORM cartodb.cdb_disable_ddl_hooks();
|
||||
|
||||
-- CDB_CartodbfyTable must not create tables, or infinite loop will happen
|
||||
PERFORM cartodb.CDB_CartodbfyTable(event_info.relation);
|
||||
|
||||
PERFORM cartodb.cdb_enable_ddl_hooks();
|
||||
|
||||
RAISE DEBUG 'Inserting into cartodb.CDB_TableMetadata';
|
||||
|
||||
-- Add entry to CDB_TableMetadata (should CartodbfyTable do this?)
|
||||
INSERT INTO cartodb.CDB_TableMetadata(tabname,updated_at)
|
||||
VALUES (event_info.relation, now());
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Table drop
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_drop_table ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_relation_drop_eventinfo();
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF (event_info.old).relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
RAISE DEBUG 'Relation % of kind % dropped from namespace oid %',
|
||||
event_info.old_relation_oid, (event_info.old).relkind, (event_info.old).relnamespace;
|
||||
|
||||
-- delete record from CDB_TableMetadata (should invalidate varnish)
|
||||
DELETE FROM cartodb.CDB_TableMetadata WHERE tabname = event_info.old_relation_oid;
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Column alter
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_alter_column ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
rel RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_column_alter_eventinfo();
|
||||
|
||||
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel;
|
||||
|
||||
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;
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF rel.relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
-- We don't want to react to alters triggered by superuser,
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
PERFORM cartodb.cdb_disable_ddl_hooks();
|
||||
|
||||
PERFORM cartodb.CDB_CartodbfyTable(event_info.relation);
|
||||
|
||||
PERFORM cartodb.cdb_enable_ddl_hooks();
|
||||
|
||||
-- update CDB_TableMetadata.updated_at (should invalidate varnish)
|
||||
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW()
|
||||
WHERE tabname = event_info.relation;
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Column drop
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_drop_column ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
rel RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_column_drop_eventinfo();
|
||||
|
||||
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel;
|
||||
|
||||
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;
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF rel.relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
-- We don't want to react to drops triggered by superuser,
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
PERFORM cartodb.cdb_disable_ddl_hooks();
|
||||
|
||||
PERFORM cartodb.CDB_CartodbfyTable(event_info.relation);
|
||||
|
||||
PERFORM cartodb.cdb_enable_ddl_hooks();
|
||||
|
||||
-- update CDB_TableMetadata.updated_at (should invalidate varnish)
|
||||
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW()
|
||||
WHERE tabname = event_info.relation;
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
-- Column add
|
||||
-- {
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_handle_add_column ()
|
||||
RETURNS event_trigger SECURITY DEFINER LANGUAGE plpgsql AS $$
|
||||
DECLARE
|
||||
event_info RECORD;
|
||||
rel RECORD;
|
||||
BEGIN
|
||||
event_info := schema_triggers.get_column_add_eventinfo();
|
||||
|
||||
SELECT oid,* FROM pg_class WHERE oid = event_info.relation INTO rel;
|
||||
|
||||
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;
|
||||
|
||||
-- We're only interested in real relations
|
||||
IF rel.relkind != 'r' THEN RETURN; END IF;
|
||||
|
||||
-- We don't want to react to drops triggered by superuser,
|
||||
IF current_setting('is_superuser') = 'on' THEN
|
||||
RAISE DEBUG 'no ddl trigger for superuser';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- update CDB_TableMetadata.updated_at (should invalidate varnish)
|
||||
UPDATE cartodb.CDB_TableMetadata SET updated_at = NOW()
|
||||
WHERE tabname = event_info.relation;
|
||||
|
||||
END; $$;
|
||||
-- }
|
||||
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_disable_ddl_hooks() returns void AS $$
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_relation_create;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_relation_drop;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_alter_column;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_drop_column;
|
||||
DROP EVENT TRIGGER IF EXISTS cdb_on_add_column;
|
||||
$$ LANGUAGE sql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_enable_ddl_hooks() returns void AS $$
|
||||
SELECT cartodb.cdb_disable_ddl_hooks();
|
||||
CREATE EVENT TRIGGER cdb_on_relation_create
|
||||
ON "relation_create" EXECUTE PROCEDURE cartodb.cdb_handle_create_table();
|
||||
CREATE EVENT TRIGGER cdb_on_relation_drop
|
||||
ON "relation_drop" EXECUTE PROCEDURE cartodb.cdb_handle_drop_table();
|
||||
CREATE EVENT TRIGGER cdb_on_alter_column
|
||||
ON "column_alter" EXECUTE PROCEDURE cartodb.cdb_handle_alter_column();
|
||||
CREATE EVENT TRIGGER cdb_on_drop_column
|
||||
ON "column_drop" EXECUTE PROCEDURE cartodb.cdb_handle_drop_column();
|
||||
CREATE EVENT TRIGGER cdb_on_add_column
|
||||
ON "column_add" EXECUTE PROCEDURE cartodb.cdb_handle_add_column();
|
||||
$$ LANGUAGE sql;
|
||||
|
||||
-- Do not enable hooks by default
|
||||
--SELECT cartodb.cdb_enable_ddl_hooks();
|
||||
@@ -2,7 +2,7 @@
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION CDB_DateToNumber(input timestamp)
|
||||
RETURNS double precision AS $$
|
||||
DECLARE output double precision DEFAULT NULL;
|
||||
DECLARE output double precision;
|
||||
BEGIN
|
||||
BEGIN
|
||||
SELECT extract (EPOCH FROM input) INTO output;
|
||||
|
||||
2
scripts-available/CDB_ExtensionPost.sql
Normal file
2
scripts-available/CDB_ExtensionPost.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
SELECT pg_catalog.pg_extension_config_dump('cartodb.cdb_tablemetadata','');
|
||||
|
||||
13
scripts-available/CDB_ExtensionUtils.sql
Normal file
13
scripts-available/CDB_ExtensionUtils.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
CREATE OR REPLACE FUNCTION cartodb.cdb_extension_reload() RETURNS void
|
||||
AS $$
|
||||
DECLARE
|
||||
ver TEXT;
|
||||
sql TEXT;
|
||||
BEGIN
|
||||
ver := split_part(cartodb.cdb_version(), ' ', 1);
|
||||
sql := 'ALTER EXTENSION cartodb UPDATE TO ''' || ver || 'next''';
|
||||
EXECUTE sql;
|
||||
sql := 'ALTER EXTENSION cartodb UPDATE TO ''' || ver || '''';
|
||||
EXECUTE sql;
|
||||
END;
|
||||
$$ language 'plpgsql' VOLATILE;
|
||||
@@ -27,7 +27,7 @@ $$ LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
-- as the extent.
|
||||
--
|
||||
--
|
||||
DROP FUNCTION IF EXISTS CDB_HexagonGrid(ext GEOMETRY, side FLOAT8);
|
||||
-- DROP FUNCTION IF EXISTS CDB_HexagonGrid(ext GEOMETRY, side FLOAT8);
|
||||
CREATE OR REPLACE FUNCTION CDB_HexagonGrid(ext GEOMETRY, side FLOAT8, origin GEOMETRY DEFAULT NULL)
|
||||
RETURNS SETOF GEOMETRY
|
||||
AS $$
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
-- Return an array of statements found in the given query text
|
||||
--
|
||||
-- Curtesy of Hubert Lubaczewski (depesz)
|
||||
-- Regexp curtesy of Hubert Lubaczewski (depesz)
|
||||
-- Implemented in plpython for performance reasons
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION CDB_QueryStatements(query text)
|
||||
RETURNS SETOF TEXT AS $$
|
||||
SELECT stmt FROM (
|
||||
SELECT btrim(q[1], E' \n\t\r;') as stmt FROM (
|
||||
SELECT regexp_matches( $1, $REG$((?:[^'"$;]+|"[^"]*"|'(?:[^']*|'')*'|(\$[^$]*\$).*?\2)+)$REG$, 'g' ) as q
|
||||
) i
|
||||
) j
|
||||
WHERE stmt <> '';
|
||||
$$ language sql IMMUTABLE STRICT;
|
||||
import re
|
||||
pat = re.compile( r'''((?:[^'"$;]+|"[^"]*"|'[^']*'|(\$[^$]*\$).*?\2)+)''', re.DOTALL )
|
||||
for match in pat.findall(query):
|
||||
cleaned = match[0].strip()
|
||||
if ( cleaned ):
|
||||
yield cleaned
|
||||
$$ language 'plpythonu' IMMUTABLE STRICT;
|
||||
|
||||
@@ -50,7 +50,7 @@ BEGIN
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
|
||||
SELECT CDB_UserDataSize() INTO quota;
|
||||
SELECT public.CDB_UserDataSize() INTO quota;
|
||||
IF quota > qmax THEN
|
||||
RAISE EXCEPTION 'Quota exceeded by %KB', (quota-qmax)/1024;
|
||||
ELSE RAISE DEBUG 'User quota in bytes: % < % (max allowed)', quota, qmax;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
DO LANGUAGE 'plpgsql' $$
|
||||
BEGIN
|
||||
IF NOT EXISTS ( SELECT * FROM pg_roles WHERE rolname= 'cdb_org_admin' )
|
||||
THEN
|
||||
CREATE ROLE cdb_org_admin NOLOGIN;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS ( SELECT * FROM pg_roles WHERE rolname= 'cdb_org_user' )
|
||||
THEN
|
||||
CREATE ROLE cdb_org_user NOLOGIN;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
@@ -2,7 +2,7 @@
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION CDB_StringToDate(input character varying)
|
||||
RETURNS date AS $$
|
||||
DECLARE output DATE DEFAULT NULL;
|
||||
DECLARE output DATE;
|
||||
BEGIN
|
||||
BEGIN
|
||||
output := input::date;
|
||||
|
||||
@@ -17,10 +17,11 @@ AS $$
|
||||
ON pg_class.oid = idx.indexrelid
|
||||
WHERE pg_indexes.tablename = '' || $1 || ''
|
||||
AND '' || $1 || '' IN (SELECT CDB_UserTables())
|
||||
AND pg_class.relname=pg_indexes.indexname;
|
||||
AND pg_class.relname=pg_indexes.indexname
|
||||
;
|
||||
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
-- This is a private function, so only the db owner need privileges
|
||||
REVOKE ALL ON FUNCTION CDB_TableIndexes(REGCLASS) FROM PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION CDB_TableIndexes(REGCLASS) TO ":DATABASE_USERNAME";
|
||||
-- This is to migrate from pre-0.2.0 version
|
||||
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36
|
||||
GRANT EXECUTE ON FUNCTION CDB_TableIndexes(REGCLASS) TO public;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
--
|
||||
-- Currently accepted permissions are: 'public', 'private' or 'all'
|
||||
--
|
||||
DROP FUNCTION IF EXISTS CDB_UserTables(); -- replaced by:
|
||||
CREATE OR REPLACE FUNCTION CDB_UserTables(perm text DEFAULT 'all')
|
||||
RETURNS SETOF information_schema.sql_identifier
|
||||
AS $$
|
||||
@@ -26,14 +25,17 @@ AS $$
|
||||
FROM usertables
|
||||
)
|
||||
SELECT t FROM perms
|
||||
WHERE p = CASE WHEN $1 = 'private' THEN false
|
||||
WHERE (
|
||||
p = CASE WHEN $1 = 'private' THEN false
|
||||
WHEN $1 = 'public' THEN true
|
||||
ELSE not p -- none
|
||||
END
|
||||
OR $1 = 'all'
|
||||
)
|
||||
AND has_table_privilege('public'||'.'||t, 'SELECT')
|
||||
;
|
||||
$$ LANGUAGE 'sql';
|
||||
|
||||
-- This is a private function, so only the db owner need privileges
|
||||
REVOKE ALL ON FUNCTION CDB_UserTables(text) FROM PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION CDB_UserTables(text) TO ":DATABASE_USERNAME";
|
||||
-- This is to migrate from pre-0.2.0 version
|
||||
-- See http://github.com/CartoDB/cartodb-postgresql/issues/36
|
||||
GRANT EXECUTE ON FUNCTION CDB_UserTables(text) TO public;
|
||||
|
||||
Reference in New Issue
Block a user