-- Verify rejected values and prefixed errors SET lc_messages = 'C'; -- Reject NULL for non-nullable columns SELECT pgch_roundtrip('Int32', NULL::int4); ERROR: pgch: cannot append NULL to NOT NULL Int32 column "c" SELECT pgch_roundtrip('Array(Int32)', NULL::int4[]); ERROR: pgch: cannot append NULL to NOT NULL Array(Int32) column "c" SELECT pgch_roundtrip('LowCardinality(String)', NULL::text); ERROR: pgch: cannot append NULL to NOT NULL LowCardinality(String) column "c" -- Reject incompatible PostgreSQL source types SELECT pgch_roundtrip('Int32', 'x'::text); ERROR: pgch: cannot encode text into ClickHouse Int32 (column "c") SELECT pgch_roundtrip('Array(Int32)', 1::int4); ERROR: pgch: cannot encode integer into ClickHouse Array(Int32) (column "c") SELECT pgch_roundtrip('Array(Int32)', ARRAY['x']::text[]); ERROR: pgch: cannot encode text into ClickHouse Array(Int32) (column "c") SELECT pgch_roundtrip('IPv4', '::1'::inet); ERROR: pgch: inet family mismatch for column "c" -- Reject missing scalar and element casts SELECT pgch_roundtrip('Array(Int128)', ARRAY[1]::int4[]); ERROR: pgch: unsupported column type "Int128" (column "c") SELECT pgch_roundtrip('Int32', '(1,2)'::point); ERROR: pgch: cannot encode point into ClickHouse Int32 (column "c") -- Reject values outside destination domain SELECT pgch_roundtrip('Decimal(9,2)', 'NaN'::numeric); ERROR: pgch: cannot encode "NaN" as ClickHouse Decimal SELECT pgch_roundtrip('Enum8('' a'' = 1)', 'z'::text); ERROR: pgch: enum value 'z' not found SELECT pgch_roundtrip('Decimal(9,2)', 1000000000::numeric); ERROR: pgch: value "1000000000" out of range for ClickHouse Decimal32 SELECT pgch_roundtrip('Decimal(18,0)', 99999999999999999999::numeric); ERROR: pgch: value "99999999999999999999" out of range for ClickHouse Decimal64 -- Reject unsupported encoder types SELECT pgch_encode('Tuple(Int32)', ROW(1)::record); ERROR: pgch: cannot encode record into ClickHouse Tuple(Int32) (column "c") SELECT pgch_encode('LowCardinality(Int32)', 1::int4); ERROR: pgch: unsupported LowCardinality variant: Int32 -- Reject Tuple targets with incompatible shape CREATE TYPE twofields AS (a int, b text); SELECT pgch_decode_as(pgch_block('Tuple(Int32)', 1, '\x2a000000'::bytea), NULL::int); ERROR: pgch: cannot return Tuple(Int32) as integer -- PostgreSQL changes composite conversion detail text between versions \set VERBOSITY terse SELECT pgch_decode_as(pgch_block('Tuple(Int32)', 1, '\x2a000000'::bytea), NULL::twofields); ERROR: could not map tuple to returned type SELECT pgch_decode_as(pgch_block('Tuple(Int32, Int32)', 1, '\x2a0000002a000000'::bytea), NULL::twofields); ERROR: could not map tuple to returned type \set VERBOSITY default -- Reject Tuple field counts other than the column's arity SELECT pgch_encode_pairs('Map(String, Int64)', ARRAY['a'], ARRAY[1]::bigint[], 1); ERROR: pgch: Tuple took 1 of 2 values SELECT pgch_encode_pairs('Map(String, Int64)', ARRAY['a'], ARRAY[1]::bigint[], 3); ERROR: pgch: Tuple takes 2 values SELECT pgch_encode_pairs('Tuple(String, Int64)', ARRAY['a'], ARRAY[1]::bigint[]); ERROR: pgch: Array value into column "c" SELECT pgch_encode_pairs('Map(String)', ARRAY['a'], ARRAY[1]::bigint[]); ERROR: pgch: Map wants key and value -- Reject types without PostgreSQL mapping SELECT pgch_pgtype('Int128'); ERROR: pgch: unsupported column type "Int128" SELECT pgch_pgtype('Nonsense'); ERROR: pgch: type parse: unknown type: Nonsense -- Reject unsupported types before reading rows, including nested types SELECT pgch_decode(pgch_block('Tuple()', 0, ''::bytea)); ERROR: decode: returned tuple is empty (column "c") SELECT pgch_decode(pgch_block('Map(String)', 0, ''::bytea)); ERROR: decode: returned map wants key and value (column "c") SELECT pgch_decode(pgch_block('Array(Nothing)', 0, ''::bytea)); ERROR: decode: no PG array type for column type "Nothing" (column "c") SELECT pgch_decode(pgch_block('LowCardinality(Int32)', 0, ''::bytea)); ERROR: decode: unsupported LowCardinality inner type (column "c") SELECT pgch_decode(pgch_block('Array(Int128)', 1, '\x0000000000000000'::bytea)); ERROR: decode: unsupported column type "Int128" (column "c") SELECT pgch_decode(pgch_block('Tuple(Int32, Map(String, Int128))', 0, ''::bytea)); ERROR: decode: unsupported column type "Int128" (column "c") -- Identify unnamed columns by position SELECT pgch_decode('\x01000006'::bytea || convert_to('Int128', 'UTF8')); ERROR: decode: unsupported column type "Int128" (column 1) -- Accept supported LowCardinality String forms SELECT pgch_decode(pgch_block('LowCardinality(String)', 0, ''::bytea)); pgch_decode ------------- {} (1 row) SELECT pgch_decode(pgch_block('LowCardinality(Nullable(String))', 0, ''::bytea)); pgch_decode ------------- {} (1 row) -- Reject UInt64 values outside bigint range SELECT pgch_decode(pgch_block('UInt64', 1, '\xffffffffffffffff'::bytea)); ERROR: pgch: value 18446744073709551615 is out of range of bigint -- Reject DateTime64 outside timestamp range SELECT pgch_decode(pgch_block('DateTime64(0)', 1, '\x0000000000000080'::bytea)); ERROR: pgch: DateTime64 value out of range -- Reject nested arrays PostgreSQL cannot represent, [[1,2],[3]] SELECT pgch_decode(pgch_block('Array(Array(Int32))', 1, '\x0200000000000000'::bytea || '\x02000000000000000300000000000000'::bytea || '\x010000000200000003000000'::bytea)); ERROR: pgch: nested arrays must have sub-arrays with matching dimensions -- Reject forged array offsets that would read past inner column SELECT pgch_decode(pgch_block('Array(Int32)', 2, '\x05000000000000000200000000000000'::bytea || '\x0100000002000000'::bytea)); ERROR: decode: array offsets not monotonic at row 1: 2 < 5 (column "c") -- Reject truncated streams and incompatible schema changes SELECT pgch_decode('\x0103'::bytea); ERROR: decode: ioless buffer drained SELECT pgch_decode(pgch_encode_rows('Int32', ARRAY[1]::int4[]) || pgch_encode_rows('String', ARRAY['a']::text[])); ERROR: decode: block column 1 type changed -- Reject chunk streams ending within a block SELECT pgch_decode_chunks(substring(pgch_encode_rows('Int32', ARRAY[1, 2]::int4[]) FROM 1 FOR 12), 4); ERROR: decode: short read