I'm trying to trim INSERT/UPDATE generic records on every table on the DB to remove any whitespace before and after each text value (i.e. change " value " in "value").
I took a look at Generic string trimming trigger for Postgresql, but this works only on INSERT records since ARGV exists only during that event.
What I thought to do was to convert NEW into a jsonb, that now I assume has the form of {"key1":"value1","key2":"value2"}, but I don't know how to cycle through its fields to trim its values.
I plan to use a
SELECT
column_name
FROM
information_schema.columns
WHERE
table_name = TG_TABLE_NAME AND table_schema = TG_TABLE_SCHEMA AND (data_type = 'text' OR data_type = 'character varying' )
to get only the "key1" (columns) having type string, so the script is something along the lines of
CREATE OR REPLACE FUNCTION a_trigger() RETURNS trigger AS $trim_trigger$
DECLARE
j jsonb = to_jsonb(NEW);
current_column text;
BEGIN
FOR current_column IN
SELECT
column_name
FROM
information_schema.columns
WHERE
table_name = TG_TABLE_NAME AND table_schema = TG_TABLE_SCHEMA AND (data_type = 'text' OR data_type = 'character varying' )
LOOP
IF j ->> current_column IS NOT NULL THEN
j = jsonb_set(j, j ->> current_column, to_jsonb(regexp_replace(j ->> current_column, '^\s*|\s*$', '', 'g')),false);
END IF;
END LOOP;
NEW = jsonb_populate_record(NEW, j);
RETURN NEW;
END;
$trim_trigger$ LANGUAGE plpgsql;
I'm having problems using jsonb_set; its signature is "jsonb, text[], jsonb, bool" but j ->> current_column is a text, and maybe I haven't fully understand the 'path' parameter.
What am I missing here?
In the end I managed with a
j = jsonb_set(j, concat('{',current_column,'}')::text[], to_jsonb(regexp_replace(j ->> current_column, '^\s*|\s*$', '', 'g')),false);
( I added a cast to text[] )
But it seems a bit dirty to me