Drops CDB_Trim_Octets for CDB_Octet_Truncate

This commit is contained in:
Guido Fioravantti 2015-10-26 18:01:03 +01:00
parent 2e701f73ba
commit bb54eb83c1
3 changed files with 71 additions and 56 deletions

View File

@ -5,20 +5,21 @@ CREATE OR REPLACE FUNCTION cartodb._CDB_Unique_Identifier(prefix TEXT, relname T
RETURNS TEXT RETURNS TEXT
AS $$ AS $$
DECLARE DECLARE
maxlen CONSTANT INTEGER := 63;
rec RECORD; rec RECORD;
usedspace INTEGER; usedspace INTEGER;
ident TEXT; ident TEXT;
i INTEGER;
origident TEXT; origident TEXT;
maxlen CONSTANT integer := 63; i INTEGER;
BEGIN BEGIN
-- Accounts for the _XX incremental suffix in case the identifier is taken -- Accounts for the _XX incremental suffix in case the identifier is taken
usedspace := 3; usedspace := 3;
usedspace := usedspace + coalesce(octet_length(prefix), 0); usedspace := usedspace + coalesce(octet_length(prefix), 0);
usedspace := usedspace + coalesce(octet_length(suffix), 0); usedspace := usedspace + coalesce(octet_length(suffix), 0);
relname := _CDB_Trim_Octets(relname, usedspace + octet_length(relname) - maxlen); relname := _CDB_Octet_Truncate(relname, maxlen - usedspace);
IF relname = '' THEN IF relname = '' THEN
PERFORM _CDB_Error('prefixes are to long to generate a valid identifier', '_CDB_Unique_Identifier'); PERFORM _CDB_Error('prefixes are to long to generate a valid identifier', '_CDB_Unique_Identifier');
@ -57,26 +58,28 @@ BEGIN
END; END;
$$ LANGUAGE 'plpgsql'; $$ LANGUAGE 'plpgsql';
-- UTF8 safe and lenght aware. Find a unique identifier for a column with a given prefix -- UTF8 safe and lenght aware. Find a unique identifier for a column with a given prefix
-- and/or suffix and withing a realtion. -- and/or suffix and withing a realtion.
CREATE OR REPLACE FUNCTION cartodb._CDB_Unique_Column_Identifier(prefix TEXT, relname TEXT, suffix TEXT, reloid REGCLASS) CREATE OR REPLACE FUNCTION cartodb._CDB_Unique_Column_Identifier(prefix TEXT, relname TEXT, suffix TEXT, reloid REGCLASS)
RETURNS TEXT RETURNS TEXT
AS $$ AS $$
DECLARE DECLARE
maxlen CONSTANT INTEGER := 63;
rec RECORD; rec RECORD;
usedspace INTEGER; usedspace INTEGER;
ident TEXT; ident TEXT;
i INTEGER;
origident TEXT; origident TEXT;
maxlen CONSTANT integer := 63; i INTEGER;
BEGIN BEGIN
-- Accounts for the _XX incremental suffix in case the identifier is taken -- Accounts for the _XX incremental suffix in case the identifier is taken
usedspace := 3; usedspace := 3;
usedspace := usedspace + coalesce(octet_length(prefix), 0); usedspace := usedspace + coalesce(octet_length(prefix), 0);
usedspace := usedspace + coalesce(octet_length(suffix), 0); usedspace := usedspace + coalesce(octet_length(suffix), 0);
relname := _CDB_Trim_Octets(relname, usedspace + octet_length(relname) - maxlen); relname := _CDB_Octet_Truncate(relname, maxlen - usedspace);
IF relname = '' THEN IF relname = '' THEN
PERFORM _CDB_Error('prefixes are to long to generate a valid identifier', '_CDB_Unique_Column_Identifier'); PERFORM _CDB_Error('prefixes are to long to generate a valid identifier', '_CDB_Unique_Column_Identifier');
@ -109,47 +112,43 @@ BEGIN
END; END;
$$ LANGUAGE 'plpgsql'; $$ LANGUAGE 'plpgsql';
-- Trims the end of a given string by the given number of octets taking care
-- not to leave characters in half. If a negative or 0 amount of octects to trim -- Truncates a given string to a max_octets octexts taking care
-- is specified, the suplied text is returned unaltered. UTF8 safe. -- not to leave characters in half. UTF8 safe.
CREATE OR REPLACE FUNCTION cartodb._CDB_Trim_Octets(totrim TEXT, octets INTEGER) CREATE OR REPLACE FUNCTION cartodb._CDB_Octet_Truncate(string TEXT, max_octets INTEGER)
RETURNS TEXT RETURNS TEXT
AS $$ AS $$
DECLARE DECLARE
extcharlen CONSTANT INTEGER := octet_length('ñ');
expected INTEGER; expected INTEGER;
examined INTEGER; examined INTEGER;
totrimlen INTEGER; strlen INTEGER;
charlen INTEGER;
i INTEGER; i INTEGER;
tail TEXT;
trimmed TEXT;
BEGIN BEGIN
charlen := bit_length('a');
totrimlen := char_length(totrim);
expected := totrimlen * charlen;
examined := bit_length(totrim);
IF octets <= 0 THEN IF max_octets <= 0 THEN
RETURN totrim;
ELSIF expected = examined THEN
RETURN SUBSTRING(totrim from 1 for (totrimlen - octets));
ELSIF (octets * charlen) > examined THEN
RETURN ''; RETURN '';
ELSIF max_octets >= octet_length(string) THEN
RETURN string;
END IF; END IF;
i := totrimlen - ((octets - 1) / 2); strlen := char_length(string);
LOOP
tail := SUBSTRING(totrim from i for totrimlen);
EXIT WHEN octet_length(tail) >= octets OR i <= 0; expected := char_length(string);
examined := octet_length(string);
i := i - 1; IF expected = examined THEN
RETURN SUBSTRING(string from 1 for max_octets);
END IF;
i := max_octets / extcharlen;
WHILE octet_length(SUBSTRING(string from 1 for i)) <= max_octets LOOP
i := i + 1;
END LOOP; END LOOP;
trimmed := SUBSTRING(totrim from 1 for (totrimlen - char_length(tail))); RETURN SUBSTRING(string from 1 for (i - 1));
RETURN trimmed;
END; END;
$$ LANGUAGE 'plpgsql'; $$ LANGUAGE 'plpgsql';

View File

@ -54,67 +54,75 @@ CREATE TABLE piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix (name t
SELECT * FROM cartodb._CDB_Unique_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', '_suffix'); SELECT * FROM cartodb._CDB_Unique_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', '_suffix');
DROP TABLE piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix; DROP TABLE piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix;
CREATE TABLE test (name text);
-- Test unique identifier creation with normal length normal colname -- Test unique identifier creation with normal length normal colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'colname', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'colname', NULL, 'test'::regclass);
-- Test unique identifier creation with prefix with normal length normal colname -- Test unique identifier creation with prefix with normal length normal colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'colname', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'colname', NULL, 'test'::regclass);
-- Test unique identifier creation with suffix with normal length normal colname -- Test unique identifier creation with suffix with normal length normal colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'colname', '_suffix'); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'colname', '_suffix', 'test'::regclass);
-- Test unique identifier creation with long length normal colname -- Test unique identifier creation with long length normal colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL, 'test'::regclass);
-- Test unique identifier creation with prefix with long length normal colname -- Test unique identifier creation with prefix with long length normal colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL, 'test'::regclass);
DROP TABLE test;
-- Test new identifier is found when name is taken from previous case -- Test new identifier is found when name is taken from previous case
CREATE TABLE test (prefix_largolargolargolargolargolargolargolargolargolargolar text); CREATE TABLE test (prefix_largolargolargolargolargolargolargolargolargolargolar text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'largolargolargolargolargolargolargolargolargolargolargolargolar', NULL, 'test'::regclass);
DROP TABLE test; DROP TABLE test;
-- Test unique identifier creation with suffix with long length normal colname -- Test unique identifier creation with suffix with long length normal colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix'); CREATE TABLE test (name text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix', 'test'::regclass);
DROP TABLE test;
-- Test new identifier is found when name is taken from previous case -- Test new identifier is found when name is taken from previous case
CREATE TABLE test (largolargolargolargolargolargolargolargolargolargolar_suffix text); CREATE TABLE test (largolargolargolargolargolargolargolargolargolargolar_suffix text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix'); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'largolargolargolargolargolargolargolargolargolargolargolargolar', '_suffix', 'test'::regclass);
DROP TABLE test; DROP TABLE test;
CREATE TABLE test (name text);
-- Test unique identifier creation with normal length UTF8 colname -- Test unique identifier creation with normal length UTF8 colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piraña', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piraña', NULL, 'test'::regclass);
-- Test unique identifier creation with prefix with normal length UTF8 colname -- Test unique identifier creation with prefix with normal length UTF8 colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'piraña', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'piraña', NULL, 'test'::regclass);
-- Test unique identifier creation with suffix with normal length UTF8 colname -- Test unique identifier creation with suffix with normal length UTF8 colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piraña', '_suffix'); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piraña', '_suffix', 'test'::regclass);
-- Test unique identifier creation with long length UTF8 colname -- Test unique identifier creation with long length UTF8 colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', NULL, 'test'::regclass);
-- Test unique identifier creation with prefix with long length UTF8 colname -- Test unique identifier creation with prefix with long length UTF8 colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', NULL, 'test'::regclass);
DROP TABLE test;
-- Test new identifier is found when name is taken from previous case -- Test new identifier is found when name is taken from previous case
CREATE TABLE test (prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi text); CREATE TABLE test (prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', NULL); SELECT * FROM cartodb._CDB_Unique_Column_Identifier('prefix_', 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', NULL, 'test'::regclass);
DROP TABLE test; DROP TABLE test;
-- Test unique identifier creation with suffix with long length UTF8 colname -- Test unique identifier creation with suffix with long length UTF8 colname
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', '_suffix'); CREATE TABLE test (name text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', '_suffix', 'test'::regclass);
DROP TABLE test;
-- Test new identifier is found when name is taken from previous case -- Test new identifier is found when name is taken from previous case
CREATE TABLE test (piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix text); CREATE TABLE test (piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix text);
SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', '_suffix'); SELECT * FROM cartodb._CDB_Unique_Column_Identifier(NULL, 'piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácidpin', '_suffix', 'test'::regclass);
DROP TABLE test; DROP TABLE test;
-- Test _CDB_Trim_Octets simple case -- Test _CDB_Octet_Truncate simple case
SELECT * FROM cartodb._CDB_Octet_Trim('piraña', 1); SELECT * FROM cartodb._CDB_Octet_Truncate('piraña', 5);
-- Test _CDB_Octet_Trim UTF8 case -- Test _CDB_Octet_Truncate UTF8 case
SELECT * FROM cartodb._CDB_Octet_Trim('piraña', 2); SELECT * FROM cartodb._CDB_Octet_Truncate('piraña', 6);
-- Test _CDB_Octet_Trim UTF8 case -- Test _CDB_Octet_Truncate UTF8 case
SELECT * FROM cartodb._CDB_Octet_Trim('piraña', 3); SELECT * FROM cartodb._CDB_Octet_Truncate('piraña', 7);

View File

@ -22,30 +22,38 @@ piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix
CREATE TABLE CREATE TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix_0 piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix_0
DROP TABLE DROP TABLE
CREATE TABLE
colname colname
prefix_colname prefix_colname
colname_suffix colname_suffix
largolargolargolargolargolargolargolargolargolargolargolargo largolargolargolargolargolargolargolargolargolargolargolargo
prefix_largolargolargolargolargolargolargolargolargolargolar prefix_largolargolargolargolargolargolargolargolargolargolar
DROP TABLE
CREATE TABLE CREATE TABLE
prefix_largolargolargolargolargolargolargolargolargolargolar_0 prefix_largolargolargolargolargolargolargolargolargolargolar_0
DROP TABLE DROP TABLE
CREATE TABLE
largolargolargolargolargolargolargolargolargolargolar_suffix largolargolargolargolargolargolargolargolargolargolar_suffix
DROP TABLE
CREATE TABLE CREATE TABLE
largolargolargolargolargolargolargolargolargolargolar_suffix_0 largolargolargolargolargolargolargolargolargolargolar_suffix_0
DROP TABLE DROP TABLE
CREATE TABLE
piraña piraña
prefix_piraña prefix_piraña
piraña_suffix piraña_suffix
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácid piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpiñaácid
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi
DROP TABLE
CREATE TABLE CREATE TABLE
prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_0 prefix_piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_0
DROP TABLE DROP TABLE
CREATE TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix
DROP TABLE
CREATE TABLE CREATE TABLE
piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix_0 piñaácidpiñaácidpiñaácidpiñaácidpiñaácidpi_suffix_0
DROP TABLE DROP TABLE
pira
pirañ pirañ
pira piraña
pira