\unset ECHO -- Treat invalid encoding according to flag: truncate, remove, and replace. SELECT description, pgch_decode_text(pgch_encode('String',input), 1) AS truncate, pgch_decode_text(pgch_encode('String',input), 2) AS remove, pgch_decode_text(pgch_encode('String',input), 3) AS replace FROM (VALUES ('valid'::text, '\x61 63 6e'::bytea), ('nul byte', '\x61 00 6e'), ('nul & invalid octet', '\x61 00 6e 80 6f'), ('invalid octet & nul', '\x61 6e 80 6f 00 '), ('valid 2-octet sequence', '\x 61 c3 b1 6e'), ('invalid 2-octet sequence', '\x61 c3 28 6e'), ('valid 3-octet sequence', '\x 61 e2 82 a1 6e'), ('invalid 2nd in 3-octet sequence', '\x61 e2 28 a1 6e'), ('invalid 3rd in 3-octet sequence', '\x61 e2 82 28 6e'), ('valid 4-octet sequence', '\x61 63 6e f0 90 8c bc 61 63 6e'), ('invalid 2nd in 4-octet sequence', '\x61 63 6e f0 28 8c bc 61 63 6e'), ('invalid 3nd in 4-octet sequence', '\x61 63 6e f0 90 28 bc 61 63 6e'), ('invalid 4th in 4-octet sequence', '\x61 63 6e f0 28 8c 28 61 63 6e') ) x(description, input); description | truncate | remove | replace ---------------------------------+--------------+--------------+-------------- valid | {acn} | {acn} | {acn} nul byte | {a} | {an} | {an} nul & invalid octet | {a} | {an€o} | {an€o} invalid octet & nul | {an€o} | {an€o} | {an€o} valid 2-octet sequence | {añn} | {añn} | {añn} invalid 2-octet sequence | {aÃ(n} | {aÃ(n} | {aÃ(n} valid 3-octet sequence | {aâ‚¡n} | {aâ‚¡n} | {aâ‚¡n} invalid 2nd in 3-octet sequence | {aâ(¡n} | {aâ(¡n} | {aâ(¡n} invalid 3rd in 3-octet sequence | {aâ‚(n} | {aâ‚(n} | {aâ‚(n} valid 4-octet sequence | {acnð�Œ¼acn} | {acnð�Œ¼acn} | {acnð�Œ¼acn} invalid 2nd in 4-octet sequence | {acnð(Œ¼acn} | {acnð(Œ¼acn} | {acnð(Œ¼acn} invalid 3nd in 4-octet sequence | {acnð�(¼acn} | {acnð�(¼acn} | {acnð�(¼acn} invalid 4th in 4-octet sequence | {acnð(Œ(acn} | {acnð(Œ(acn} | {acnð(Œ(acn} (13 rows) -- Check output length for repeated invalid bytes under each encoding policy SELECT length((pgch_decode_text(pgch_encode('String', input), 1))[1]) AS truncate, length((pgch_decode_text(pgch_encode('String', input), 2))[1]) AS remove, length((pgch_decode_text(pgch_encode('String', input), 3))[1]) AS replace FROM (SELECT decode(repeat('61c3286e', 64), 'hex')) x(input); truncate | remove | replace ----------+--------+--------- 256 | 256 | 256 (1 row) -- Apply encoding policy when pgch_decode renders FixedString values as text SELECT description, pgch_decode(pgch_encode('FixedString(5)', input), 1) AS truncate, pgch_decode(pgch_encode('FixedString(5)', input), 2) AS remove, pgch_decode(pgch_encode('FixedString(5)', input), 3) AS replace FROM (VALUES ('padding'::text, '\x61 62'::bytea), ('padding & invalid octet', '\x61 80 62') ) x(description, input); description | truncate | remove | replace -------------------------+----------+--------+--------- padding | {ab} | {ab} | {ab} padding & invalid octet | {a€b} | {a€b} | {a€b} (2 rows) -- Allow trailing NUL padding in FixedString even when invalid bytes cause errors SELECT pgch_decode(pgch_encode('FixedString(5)', '\x6162'::bytea)) AS fail; fail ------ {ab} (1 row) -- Validate the encoding_check parser. SELECT x, pgch_encoding_check_enum(x::text) AS num FROM ( VALUES ('fail'), ('replace'), ('truncate'), ('remove'), ('nonesuch'), ('Fail'), ('TRUNCATE'), ('rePlaCe'), ('removE'), ('noneSuch') ) x(x); x | num ----------+----- fail | 0 replace | 3 truncate | 1 remove | 2 nonesuch | Fail | 0 TRUNCATE | 1 rePlaCe | 3 removE | 2 noneSuch | (10 rows)