Home > Blockchain >  Postgres replacing 'text' with e'text'
Postgres replacing 'text' with e'text'

Time:03-09

I inserted a bunch of rows with a text field like content='...\n...\n...'.

I didn't use e in front, like conent=e'...\n...\n..., so now \n is not actually displayed as a newline - it's printed as text.

How do I fix this, i.e. how to change every row's content field from '...' to e'...'?

CodePudding user response:

Use REPLACE in an update query. Something like this: (I'm on mobile so please ignore any typo or syntax erro)

UPDATE table
SET 
column = REPLACE(column, '\n', e'\n')

CodePudding user response:

The syntax variant E'string' makes Postgres interpret the given string as Posix escape string. \n encoding a newline is only one of many interpreted escape sequences (even if the most common one). See:

To "re-evaluate" your Posix escape string, you could use a simple function with dynamic SQL like this:

CREATE OR REPLACE FUNCTION f_eval_posix_escapes(INOUT _string text)
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE 'SELECT E''' || _string || ''''  INTO _string;
END
$func$;

WARNING 1: This is inherently unsafe! We have to evaluate input strings dynamically without quoting and escaping, which allows SQL injection. Only use this in a safe environment.

WARNING 2: Don't apply repeatedly. Or it will misinterpret your actual string with genuine \ characters, etc.

WARNING 3: This simple function is imperfect as it cannot cope with nested single quotes properly. If you have some of those, consider instead:

Apply:

UPDATE tbl
SET    content = f_eval_posix_escapes(content)
WHERE  content IS DISTINCT FROM f_eval_posix_escapes(content);

db<>fiddle here

Note the added WHERE clause to skip updates that would not change anything. See:

  • Related