Re-use columns named 'cartodb_id' if the values of the

keys are in fact unique.
master
Paul Ramsey 10 years ago
parent 74b7740892
commit 8dc7f45cca

@ -692,6 +692,8 @@ $$ LANGUAGE PLPGSQL;
-- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-- TODO: Handing the case of 'cartodb_id' column with integer non-primary key
-- TODO: Preserve that column, IFF it has unique values
-- Find out if the table already has a usable primary key -- Find out if the table already has a usable primary key
-- If the table has both a usable key and usable geometry -- If the table has both a usable key and usable geometry
@ -704,6 +706,7 @@ DECLARE
rec RECORD; rec RECORD;
i INTEGER; i INTEGER;
sql TEXT; sql TEXT;
useable_key BOOLEAN = false;
BEGIN BEGIN
RAISE DEBUG 'Entered _CDB_Has_Usable_Primary_ID'; RAISE DEBUG 'Entered _CDB_Has_Usable_Primary_ID';
@ -719,25 +722,66 @@ BEGIN
AND NOT a.attisdropped AND NOT a.attisdropped
AND a.attname = keyname; AND a.attname = keyname;
-- It's perfect (named right, right type, right index)! -- Found something named right...
IF FOUND AND rec.indisprimary AND rec.indisunique AND rec.attnotnull AND rec.atttypid IN (20,21,23) THEN IF FOUND THEN
-- And it's an integer column...
IF rec.atttypid IN (20,21,23) THEN
-- And it's a unique primary key! Done!
IF rec.indisprimary AND rec.indisunique AND rec.attnotnull THEN
RAISE DEBUG '_CDB_Has_Usable_Primary_ID found good ''%''', keyname; RAISE DEBUG '_CDB_Has_Usable_Primary_ID found good ''%''', keyname;
RETURN true; RETURN true;
-- It's an integer and it's named 'cartodb_id' maybe it is usable -- Check and see if the column values are unique,
-- ELSIF rec.atttypid IN (20,21,23) THEN -- if they are, we can use this column...
ELSE
-- Assume things are OK until proven otherwise...
useable_key := true;
BEGIN
sql := Format('ALTER TABLE %s ADD CONSTRAINT %s_unique UNIQUE (%s)', reloid::text, keyname, keyname);
RAISE DEBUG '_CDB_Has_Usable_Primary_ID: %', sql;
EXECUTE sql;
EXCEPTION
-- Failed unique check...
WHEN unique_violation THEN
RAISE NOTICE '_CDB_Has_Usable_Primary_ID column % is not unique', keyname;
useable_key := false;
-- Other fatal error
WHEN others THEN
RAISE EXCEPTION 'Cartodbfying % (%s): % (%)', reloid::text, keyname, SQLERRM, SQLSTATE;
END;
-- It's not suitable (not an integer?, not unique?) to rename it out of the way -- Clean up test constraint
ELSIF FOUND THEN IF useable_key THEN
RAISE DEBUG '_CDB_Has_Usable_Primary_ID found bad ''%'', renaming it', keyname; EXECUTE Format('ALTER TABLE %s DROP CONSTRAINT %s_unique', reloid::text, keyname);
-- Move non-unique column out of the way
ELSE
RAISE DEBUG '_CDB_Has_Usable_Primary_ID found non-unique ''%'', renaming it', keyname;
sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %s', sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %s',
reloid::text, rec.attname, _CDB_Unique_Column_Name(reloid, keyname)); reloid::text, rec.attname, _CDB_Unique_Column_Name(reloid, keyname));
RAISE DEBUG '_CDB_Has_Usable_Primary_ID: %', sql; RAISE DEBUG '_CDB_Has_Usable_Primary_ID: %', sql;
EXECUTE sql; EXECUTE sql;
END IF;
END IF;
-- It's not an integer column, we have to rename it
ELSE
RAISE DEBUG '_CDB_Has_Usable_Primary_ID found non-integer ''%'', renaming it', keyname;
sql := Format('ALTER TABLE %s RENAME COLUMN %s TO %s',
reloid::text, rec.attname, _CDB_Unique_Column_Name(reloid, keyname));
RAISE DEBUG '_CDB_Has_Usable_Primary_ID: %', sql;
EXECUTE sql;
END IF;
-- There's no column there named keyname -- There's no column there named keyname
ELSE ELSE

Loading…
Cancel
Save