cartodb-postgresql/scripts-available/CDB_DigitSeparator.sql
2019-05-31 15:37:15 +02:00

54 lines
1.4 KiB
PL/PgSQL

-- Find thousand and decimal digits separators
CREATE OR REPLACE FUNCTION @extschema@.CDB_DigitSeparator (rel REGCLASS, fld TEXT, OUT t CHAR, OUT d CHAR)
as $$
DECLARE
sql TEXT;
rec RECORD;
BEGIN
-- We're only interested in rows with either "," or '.'
sql := 'SELECT ' || quote_ident(fld) || ' as f FROM ' || rel::text
|| ' WHERE ' || quote_ident(fld) || ' ~ ''[,.]''';
FOR rec IN EXECUTE sql
LOOP
-- Any separator appearing more than once
-- will be assumed to be thousand separator
IF rec.f ~ ',.*,' THEN
t := ','; d := '.';
RETURN;
ELSIF rec.f ~ '\..*\.' THEN
t := '.'; d := ',';
RETURN;
END IF;
-- If both separator are present, rightmost
-- will be assumed to be decimal separator
IF rec.f ~ '\.' AND rec.f ~ ',' THEN
rec.f = reverse(rec.f);
IF strpos(rec.f, ',') < strpos(rec.f, '.') THEN
t := '.'; d := ',';
ELSE
t := ','; d := '.';
END IF;
RETURN;
END IF;
-- A separator NOT followed by 3 digits
-- will be assumed to be decimal separator
IF rec.f ~ ',' AND rec.f !~ '(,[0-9]{3}$)|(,[0-9]{3}[,.])' THEN
t := '.'; d := ',';
RETURN;
ELSIF rec.f ~ '\.' AND rec.f !~ '(\.[0-9]{3}$)|(\.[0-9]{3}[,.])' THEN
t := ','; d := '.';
RETURN;
END IF;
-- Otherwise continue looking
END LOOP;
END
$$
LANGUAGE 'plpgsql' STABLE STRICT PARALLEL SAFE;