Fix cartodbfication of already-cartodbfied tables in presence of views
Closes #30 Includes testcase
This commit is contained in:
@@ -184,6 +184,7 @@ BEGIN
|
|||||||
|
|
||||||
-- We need created_at and updated_at
|
-- 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 >>
|
<< column_setup >>
|
||||||
LOOP --{
|
LOOP --{
|
||||||
had_column := FALSE;
|
had_column := FALSE;
|
||||||
@@ -204,27 +205,35 @@ BEGIN
|
|||||||
|
|
||||||
IF had_column THEN
|
IF had_column THEN
|
||||||
|
|
||||||
-- Ensure data type is a TIMESTAMP WITH TIMEZONE
|
-- Check data type is a TIMESTAMP WITH TIMEZONE
|
||||||
sql := 'ALTER TABLE ' || reloid::text
|
SELECT t.typname, t.oid, a.attnotnull FROM pg_type t, pg_attribute a
|
||||||
|| ' ALTER ' || rec.cname
|
WHERE a.atttypid = t.oid AND a.attrelid = reloid
|
||||||
|| ' SET NOT NULL,'
|
AND NOT a.attisdropped AND a.attname = rec.cname
|
||||||
|| ' ALTER ' || rec.cname
|
INTO STRICT rec2;
|
||||||
|| ' TYPE timestamptz USING ' || rec.cname || '::timestamptz,'
|
IF rec2.oid NOT IN (1184) THEN -- timestamptz {
|
||||||
|| ' ALTER ' || rec.cname
|
RAISE NOTICE 'Existing % field is of invalid type % (need timestamptz), renaming', rec.
|
||||||
|| ' SET DEFAULT now()';
|
cname, rec2.typname;
|
||||||
BEGIN
|
ELSE -- }{
|
||||||
RAISE DEBUG 'Running %', sql;
|
-- Ensure data type is a TIMESTAMP WITH TIMEZONE
|
||||||
EXECUTE sql;
|
sql := 'ALTER TABLE ' || reloid::text
|
||||||
EXIT column_setup;
|
|| ' ALTER ' || rec.cname
|
||||||
EXCEPTION
|
|| ' SET NOT NULL,'
|
||||||
WHEN not_null_violation THEN -- failed not-null
|
|| ' ALTER ' || rec.cname
|
||||||
RAISE NOTICE '%, renaming', SQLERRM;
|
|| ' SET DEFAULT now()';
|
||||||
WHEN cannot_coerce THEN -- failed cast
|
BEGIN
|
||||||
RAISE NOTICE '%, renaming', SQLERRM;
|
RAISE DEBUG 'Running %', sql;
|
||||||
WHEN others THEN
|
EXECUTE sql;
|
||||||
RAISE EXCEPTION 'Cartodbfying % (%): % (%)',
|
EXIT column_setup;
|
||||||
reloid, rec.cname, SQLERRM, SQLSTATE;
|
EXCEPTION
|
||||||
END;
|
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 'Cartodbfying % (%): % (%)',
|
||||||
|
reloid, rec.cname, SQLERRM, SQLSTATE;
|
||||||
|
END;
|
||||||
|
END IF; -- }
|
||||||
|
|
||||||
-- invalid column, need rename and re-create it
|
-- invalid column, need rename and re-create it
|
||||||
i := 0;
|
i := 0;
|
||||||
@@ -250,6 +259,28 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
END LOOP; -- }
|
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
|
||||||
|
sql := 'UPDATE ' || reloid::text || ' SET ' || rec.cname || ' = '
|
||||||
|
|| 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; -- }
|
END LOOP; -- }
|
||||||
|
|
||||||
-- We need the_geom and the_geom_webmercator
|
-- We need the_geom and the_geom_webmercator
|
||||||
|
|||||||
@@ -177,6 +177,9 @@ CREATE TABLE t AS SELECT NOW()::text as created_at,
|
|||||||
SELECT CDB_CartodbfyTableCheck('t', 'text timestamps');
|
SELECT CDB_CartodbfyTableCheck('t', 'text timestamps');
|
||||||
SELECT extract(secs from reftime-created_at),
|
SELECT extract(secs from reftime-created_at),
|
||||||
extract(secs from reftime-updated_at) FROM t;
|
extract(secs from reftime-updated_at) FROM t;
|
||||||
|
CREATE VIEW v AS SELECT * FROM t;
|
||||||
|
SELECT CDB_CartodbfyTableCheck('t', 'cartodbfied with view');
|
||||||
|
DROP VIEW v;
|
||||||
DROP TABLE t;
|
DROP TABLE t;
|
||||||
|
|
||||||
-- table with existing cartodb_id field ot type text
|
-- table with existing cartodb_id field ot type text
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ DROP TABLE
|
|||||||
SELECT 1
|
SELECT 1
|
||||||
text timestamps cartodbfied fine
|
text timestamps cartodbfied fine
|
||||||
0|0
|
0|0
|
||||||
|
CREATE VIEW
|
||||||
|
cartodbfied with view cartodbfied fine
|
||||||
|
DROP VIEW
|
||||||
DROP TABLE
|
DROP TABLE
|
||||||
SELECT 1
|
SELECT 1
|
||||||
text cartodb_id cartodbfied fine
|
text cartodb_id cartodbfied fine
|
||||||
|
|||||||
Reference in New Issue
Block a user