-- directory paths and dlsuffix are passed to us in environment variables
\getenv libdir PG_LIBDIR
\getenv dlsuffix PG_DLSUFFIX
\set regresslib :libdir '/regress' :dlsuffix
CREATE FUNCTION test_enc_setup() RETURNS void AS :'regresslib', 'test_enc_setup'
LANGUAGE C STRICT; SELECTFROM test_enc_setup();
CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUTint, result OUT bytea) AS :'regresslib', 'test_enc_conversion'
LANGUAGE C STRICT;
CREATE USER regress_conversion_user WITH NOCREATEDB NOCREATEROLE; SET SESSION AUTHORIZATION regress_conversion_user; CREATE CONVERSION myconv FOR'LATIN1'TO'UTF8'FROM iso8859_1_to_utf8; -- -- cannot make same name conversion in same schema -- CREATE CONVERSION myconv FOR'LATIN1'TO'UTF8'FROM iso8859_1_to_utf8; -- -- create default conversion with qualified name -- CREATEDEFAULT CONVERSION public.mydef FOR'LATIN1'TO'UTF8'FROM iso8859_1_to_utf8; -- -- cannot make default conversion with same schema/for_encoding/to_encoding -- CREATEDEFAULT CONVERSION public.mydef2 FOR'LATIN1'TO'UTF8'FROM iso8859_1_to_utf8; -- test comments
COMMENT ON CONVERSION myconv_bad IS'foo';
COMMENT ON CONVERSION myconv IS'bar';
COMMENT ON CONVERSION myconv ISNULL; -- -- drop user defined conversion -- DROP CONVERSION myconv; DROP CONVERSION mydef; -- -- Note: the built-in conversions are exercised in opr_sanity.sql, -- so there's no need to do that here. -- -- -- return to the superuser --
RESET SESSION AUTHORIZATION; DROP USER regress_conversion_user;
-- -- Test built-in conversion functions. --
-- Helper function to test a conversion. Uses the test_enc_conversion function -- that was created in the create_function_0 test. createorreplace function test_conv(
input IN bytea,
src_encoding IN text,
dst_encoding IN text,
result OUT bytea,
errorat OUT bytea,
error OUT text)
language plpgsql as
$$ declare
validlen int;
begin -- First try to perform the conversion with noError = false. If that errors out, -- capture the error message, and try again with noError = true. The second call -- should succeed and return the position of the error, return that too.
begin select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, false);
errorat = NULL;
error := NULL;
exception when others then
error := sqlerrm; select * into validlen, result from test_enc_conversion(input, src_encoding, dst_encoding, true);
errorat = substr(input, validlen + 1);
end; return;
end;
$$;
-- -- UTF-8 -- -- The description column must be unique. CREATETABLE utf8_verification_inputs (inbytes bytea, description text PRIMARYKEY); insertinto utf8_verification_inputs values
('\x66006f', 'NUL byte'),
('\xaf', 'bare continuation'),
('\xc5', 'missing second byte in 2-byte char'),
('\xc080', 'smallest 2-byte overlong'),
('\xc1bf', 'largest 2-byte overlong'),
('\xc280', 'next 2-byte after overlongs'),
('\xdfbf', 'largest 2-byte'),
('\xe9af', 'missing third byte in 3-byte char'),
('\xe08080', 'smallest 3-byte overlong'),
('\xe09fbf', 'largest 3-byte overlong'),
('\xe0a080', 'next 3-byte after overlong'),
('\xed9fbf', 'last before surrogates'),
('\xeda080', 'smallest surrogate'),
('\xedbfbf', 'largest surrogate'),
('\xee8080', 'next after surrogates'),
('\xefbfbf', 'largest 3-byte'),
('\xf1afbf', 'missing fourth byte in 4-byte char'),
('\xf0808080', 'smallest 4-byte overlong'),
('\xf08fbfbf', 'largest 4-byte overlong'),
('\xf0908080', 'next 4-byte after overlong'),
('\xf48fbfbf', 'largest 4-byte'),
('\xf4908080', 'smallest too large'),
('\xfa9a9a8a8a', '5-byte');
-- Test UTF-8 verification slow path select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_verification_inputs;
-- Test UTF-8 verification with ASCII padding appended to provide -- coverage for algorithms that work on multiple bytes at a time. -- The error message for a sequence starting with a 4-byte lead -- will contain all 4 bytes if they are present, so various -- expressions below add 3 ASCII bytes to the end to ensure -- consistent error messages. -- The number 64 below needs to be at least the value of STRIDE_LENGTH in wchar.c.
-- Test multibyte verification in fast path with test_bytes as ( select
inbytes,
description,
(test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error from utf8_verification_inputs
), test_padded as ( select
description,
(test_conv(inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error from test_bytes
) select
description,
b.error as orig_error,
p.error as error_after_padding from test_padded p join test_bytes b using (description) where p.error isdistinctfrom b.error orderby description;
-- Test ASCII verification in fast path where incomplete -- UTF-8 sequences fall at the end of the preceding chunk. with test_bytes as ( select
inbytes,
description,
(test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error from utf8_verification_inputs
), test_padded as ( select
description,
(test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 64)::bytea, 'utf8', 'utf8')).error from test_bytes
) select
description,
b.error as orig_error,
p.error as error_after_padding from test_padded p join test_bytes b using (description) where p.error isdistinctfrom b.error orderby description;
-- Test cases where UTF-8 sequences within short text -- come after the fast path returns. with test_bytes as ( select
inbytes,
description,
(test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error from utf8_verification_inputs
), test_padded as ( select
description,
(test_conv(repeat('.', 64)::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error from test_bytes
) select
description,
b.error as orig_error,
p.error as error_after_padding from test_padded p join test_bytes b using (description) where p.error isdistinctfrom b.error orderby description;
-- Test cases where incomplete UTF-8 sequences fall at the -- end of the part checked by the fast path. with test_bytes as ( select
inbytes,
description,
(test_conv(inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error from utf8_verification_inputs
), test_padded as ( select
description,
(test_conv(repeat('.', 64 - length(inbytes))::bytea || inbytes || repeat('.', 3)::bytea, 'utf8', 'utf8')).error from test_bytes
) select
description,
b.error as orig_error,
p.error as error_after_padding from test_padded p join test_bytes b using (description) where p.error isdistinctfrom b.error orderby description;
CREATETABLE utf8_inputs (inbytes bytea, description text); insertinto utf8_inputs values
('\x666f6f', 'valid, pure ASCII'),
('\xc3a4c3b6', 'valid, extra latin chars'),
('\xd184d0bed0be', 'valid, cyrillic'),
('\x666f6fe8b1a1', 'valid, kanji/Chinese'),
('\xe382abe3829a', 'valid, two chars that combine to one in EUC_JIS_2004'),
('\xe382ab', 'only first half of combined char in EUC_JIS_2004'),
('\xe382abe382', 'incomplete combination when converted EUC_JIS_2004'),
('\xecbd94eb81bceba6ac', 'valid, Hangul, Korean'),
('\x666f6fefa8aa', 'valid, needs mapping function to convert to GB18030'),
('\x66e8b1ff6f6f', 'invalid byte sequence'),
('\x66006f', 'invalid, NUL byte'),
('\x666f6fe8b100', 'invalid, NUL byte'),
('\x666f6fe8b1', 'incomplete character at end');
-- Test UTF-8 verification select description, (test_conv(inbytes, 'utf8', 'utf8')).* from utf8_inputs; -- Test conversions from UTF-8 select description, inbytes, (test_conv(inbytes, 'utf8', 'euc_jis_2004')).* from utf8_inputs; select description, inbytes, (test_conv(inbytes, 'utf8', 'latin1')).* from utf8_inputs; select description, inbytes, (test_conv(inbytes, 'utf8', 'latin2')).* from utf8_inputs; select description, inbytes, (test_conv(inbytes, 'utf8', 'latin5')).* from utf8_inputs; select description, inbytes, (test_conv(inbytes, 'utf8', 'koi8r')).* from utf8_inputs; select description, inbytes, (test_conv(inbytes, 'utf8', 'gb18030')).* from utf8_inputs;
-- Test EUC_JIS_2004 verification select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'euc_jis_2004')).* from euc_jis_2004_inputs; -- Test conversions from EUC_JIS_2004 select description, inbytes, (test_conv(inbytes, 'euc_jis_2004', 'utf8')).* from euc_jis_2004_inputs;
-- -- SHIFT-JIS-2004 -- CREATETABLE shiftjis2004_inputs (inbytes bytea, description text); insertinto shiftjis2004_inputs values
('\x666f6f', 'valid, pure ASCII'),
('\x666f6f8fdb', 'valid'),
('\x666f6f81c0', 'valid, no translation to UTF-8'),
('\x666f6f82f5', 'valid, translates to two UTF-8 chars '),
('\x666f6f8fdb8f', 'incomplete char '),
('\x666f6f820a', 'incomplete char, followed by newline '),
('\x666f6f008fdb', 'invalid, NUL byte'),
('\x666f6f8f00db', 'invalid, NUL byte'),
('\x666f6f8fdb00', 'invalid, NUL byte');
-- Test SHIFT-JIS-2004 verification select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'shiftjis2004')).* from shiftjis2004_inputs; -- Test conversions from SHIFT-JIS-2004 select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'utf8')).* from shiftjis2004_inputs; select description, inbytes, (test_conv(inbytes, 'shiftjis2004', 'euc_jis_2004')).* from shiftjis2004_inputs;
-- -- GB18030 -- CREATETABLE gb18030_inputs (inbytes bytea, description text); insertinto gb18030_inputs values
('\x666f6f', 'valid, pure ASCII'),
('\x666f6fcff3', 'valid'),
('\x666f6f8431a530', 'valid, no translation to UTF-8'),
('\x666f6f84309c38', 'valid, translates to UTF-8 by mapping function'),
('\x666f6f84309c', 'incomplete char '),
('\x666f6f84309c0a', 'incomplete char, followed by newline '),
('\x666f6f84', 'incomplete char at end'),
('\x666f6f84309c3800', 'invalid, NUL byte'),
('\x666f6f84309c0038', 'invalid, NUL byte');
-- Test GB18030 verification. Round-trip through text so the backing of the -- bytea values is palloc, not shared_buffers. This lets Valgrind detect -- reads past the end. select description, inbytes, (test_conv(inbytes::text::bytea, 'gb18030', 'gb18030')).* from gb18030_inputs; -- Test conversions from GB18030 select description, inbytes, (test_conv(inbytes, 'gb18030', 'utf8')).* from gb18030_inputs;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.