should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,142 @@
# name: test/sql/cast/boolean_autocast.test
# description: Test boolean auto casts
# group: [cast]
statement ok
PRAGMA enable_verification
# boolean <-> integer
query T
SELECT true=1;
----
true
query T
SELECT true=0;
----
false
query T
SELECT false=0;
----
true
query T
SELECT false=1;
----
false
query T
SELECT 1=true;
----
true
query T
SELECT 0=true;
----
false
query T
SELECT 0=false;
----
true
query T
SELECT 1=false;
----
false
# boolean <-> string
query T
SELECT true='1';
----
true
query T
SELECT true='1'::VARCHAR;
----
true
query T
SELECT true='0';
----
false
query T
SELECT false='0';
----
true
query T
SELECT false='1';
----
false
query T
SELECT true='true';
----
true
query T
SELECT true='false';
----
false
query T
SELECT false='false';
----
true
query T
SELECT false='true';
----
false
query T
SELECT '1'=true;
----
true
query T
SELECT '0'=true;
----
false
query T
SELECT '0'=false;
----
true
query T
SELECT '1'=false;
----
false
query T
SELECT true='true';
----
true
query T
SELECT true='false';
----
false
query T
SELECT false='false';
----
true
query T
SELECT false='true';
----
false
# failed to auto cast
statement error
SELECT false='unknownbool';
----
statement error
SELECT 'unknownbool'=false;
----

View File

@@ -0,0 +1,204 @@
# name: test/sql/cast/cast_error_location.test
# description: Test reporting error location of casts
# group: [cast]
statement ok
PRAGMA enable_verification
# unimplemented cast
statement error
SELECT 1::STRUCT(i INTEGER)
----
^
# out of range integer cast
statement error
SELECT 1000::utinyint
----
^
# string cast
statement error
SELECT 'hello'::int
----
^
# numeric -> decimal cast
statement error
SELECT 1000::decimal(2,1)
----
^
# decimal -> decimal cast
statement error
SELECT 1000.0::decimal(5,1)::decimal(2,1)
----
^
# list cast
statement error
SELECT [1000]::utinyint[]
----
^
# struct cast
statement error
SELECT {'x': 1000}::row(x tinyint)
----
^
# double -> float
statement error
select 1e308::float
----
^
# double -> hugeint
statement error
select 1e308::hugeint
----
^
# hugeint -> int
statement error
select 1000000000000000000000000000000::hugeint::int
----
^
# automatically added cast
statement error
select nth_value(42, 'hello') over ()
----
^
# dates
statement error
select '1900'::date
----
^
statement error
select 42::utinyint + 'hello'
----
^
# bit
statement error
SELECT bitstring('1', 9)::BOOL;
----
^
# array
statement error
SELECT [1,2,3]::INT[2]
----
^
# blob
statement error
SELECT '\x'::BYTEA
----
^
# now with a table
statement ok
CREATE TABLE cast_table(i INTEGER, s VARCHAR, d DECIMAL(5,1), l INT[], int_struct ROW(i INTEGER), dbl DOUBLE, hge HUGEINT, invalid_blob_str VARCHAR);
statement ok
INSERT INTO cast_table VALUES (1000, 'hello', 1000.0, [1000], {'i': 1000}, 1e308, 1000000000000000000000000000000, '\x')
# out of range integer cast
statement error
SELECT i::utinyint from cast_table
----
^
# string cast
statement error
SELECT s::int FROM cast_table
----
^
# numeric -> decimal cast
statement error
SELECT i::decimal(2,1) FROM cast_table
----
^
# decimal -> decimal cast
statement error
SELECT d::decimal(2,1) FROM cast_table
----
^
# list cast
statement error
SELECT l::utinyint[] FROM cast_table
----
^
statement error
SELECT int_struct::ROW(x TINYINT) FROM cast_table
----
<REGEX>:Binder Error.*STRUCT to STRUCT cast must have at least one matching member.*
# DOUBLE to FLOAT cast.
statement error
select dbl::float FROM cast_table
----
^
# double -> hugeint
statement error
select dbl::hugeint FROM cast_table
----
^
# hugeint -> int
statement error
select hge::hugeint::int FROM cast_table
----
^
# array
statement error
SELECT l::INT[3] FROM cast_table
----
^
# blob
statement error
SELECT invalid_blob_str::BYTEA FROM cast_table
----
^
# inserts into a table
statement ok
CREATE TABLE int_tbl AS SELECT 42 my_integer
statement ok
CREATE TABLE str_tbl AS SELECT 'hello' my_str
statement ok
CREATE TABLE ts_tbl(ts TIMESTAMP)
statement error
INSERT INTO ts_tbl SELECT my_integer FROM int_tbl
----
^
statement error
INSERT INTO ts_tbl SELECT my_integer * 2 FROM int_tbl
----
^
statement error
INSERT INTO ts_tbl FROM int_tbl
----
my_integer
statement error
INSERT INTO ts_tbl FROM str_tbl
----
my_str

View File

@@ -0,0 +1,21 @@
# name: test/sql/cast/decimal_float_cast.test
# description: Issue #2965
# group: [cast]
statement ok
PRAGMA enable_verification
query I
select cast(100000000000000000000 as double) < cast(99999999999999999999.99999 as double);
----
false
query I
select 100000000000000000000 > 99999999999999999999.99999;
----
true
query I
select cast(999999999999999.9999 as double) <= cast(999999999999999.99999999 as double);
----
true

View File

@@ -0,0 +1,20 @@
# name: test/sql/cast/decimal_integer_cast.test
# description: Issue #2965
# group: [cast]
statement ok
PRAGMA enable_verification
foreach datatype TINYINT SMALLINT INTEGER BIGINT HUGEINT
query I
SELECT CAST(0.55 AS ${datatype}) as x;
----
1
query I
SELECT CAST(-0.55 AS ${datatype}) as x;
----
-1
endloop

View File

@@ -0,0 +1,23 @@
# name: test/sql/cast/dot_function_missing_error.test
# description: Test reporting of dot with missing identifier
# group: [cast]
statement ok
PRAGMA enable_verification
# file does not exist
statement error
select file.replace('a', 'b') from (values ('xxxx')) t("filename");
----
"file" not found in FROM clause
# function does not exist
statement error
select filename.replacezxcv('a', 'b') from (values ('xxxx')) t("filename");
----
replacezxcv does not exist
statement error
select replacezxcv('a', 'b') from (values ('xxxx')) t("filename");
----
replacezxcv does not exist

View File

@@ -0,0 +1,30 @@
# name: test/sql/cast/double_float_cast.test
# description: Test out of range double -> float casts
# group: [cast]
statement ok
PRAGMA enable_verification
statement error
select 1e308::float;
----
query I
select '1e308'::float;
----
inf
query I
select '1e310'::double;
----
inf
query I
select '-1e308'::float;
----
-inf
query I
select '-1e310'::double;
----
-inf

View File

@@ -0,0 +1,17 @@
# name: test/sql/cast/float_decimal_cast.test
# description: Rounding half up in float => decimal casts
# group: [cast]
statement ok
PRAGMA enable_verification
# PG does NOT use statistical ("Banker's") rounding for floating point => decimal
foreach src FLOAT DOUBLE
query II
select 1.35::${src}::decimal(3, 1), 1.45::${src}::decimal(3, 1)
----
1.4 1.5
endloop

View File

@@ -0,0 +1,46 @@
# name: test/sql/cast/float_integer_cast.test
# description: Statistical rounding in float => int casts
# group: [cast]
statement ok
PRAGMA enable_verification
# PG uses statistical ("Banker's") rounding for floating point => integer
foreach src FLOAT DOUBLE
foreach dst TINYINT SMALLINT INTEGER BIGINT HUGEINT
query I
select cast(0.5::${src} as ${dst}) as x;
----
0
query I
select cast(0.55::${src} as ${dst}) as x;
----
1
query I
select cast(1.5::${src} as ${dst}) as x;
----
2
query I
select cast(-0.5::${src} as ${dst}) as x;
----
0
query I
select cast(-0.55::${src} as ${dst}) as x;
----
-1
query I
select cast(-1.5::${src} as ${dst}) as x;
----
-2
endloop
endloop

View File

@@ -0,0 +1,185 @@
# name: test/sql/cast/string_to_integer_decimal_cast.test
# description: String to Integer casts with Decimals
# group: [cast]
statement ok
PRAGMA enable_verification
# Positive numbers (includes unsigned)
foreach type <integral>
query I
select '0.000005'::${type};
----
0
query I
select '1.100004'::${type};
----
1
query I
select '0.5'::${type};
----
1
query I
select '1.50004'::${type};
----
2
endloop
# Negative numbers (excludes unsigned)
foreach type <signed>
query I
select '-0.000005'::${type};
----
0
query I
select '-1.100004'::${type};
----
-1
query I
select '-0.5'::${type};
----
-1
query I
select '-1.50004'::${type};
----
-2
endloop
# Check limits (signed)
query II
select '127.1'::TINYINT, '-128.1'::TINYINT;
----
127 -128
query II
select '32767.1'::SMALLINT, '-32768.1'::SMALLINT;
----
32767 -32768
query II
select '2147483647.1'::INTEGER, '-2147483648.1'::INTEGER;
----
2147483647 -2147483648
query II
select '9223372036854775807.1'::BIGINT, '-9223372036854775808.1'::BIGINT;
----
9223372036854775807 -9223372036854775808
query II
select '170141183460469231731687303715884105727.1'::HUGEINT, '-170141183460469231731687303715884105728.1'::HUGEINT;
----
170141183460469231731687303715884105727 -170141183460469231731687303715884105728
# Check limits (unsigned)
query I
select '255.1'::UTINYINT;
----
255
query I
select '65535.1'::USMALLINT;
----
65535
query I
select '4294967295.1'::UINTEGER;
----
4294967295
query I
select '18446744073709551615.1'::UBIGINT;
----
18446744073709551615
query I
select '340282366920938463463374607431768211455.1'::UHUGEINT;
----
340282366920938463463374607431768211455
# going above the limit should error (signed)
statement error
select '127.5'::TINYINT;
----
Conversion Error
statement error
select '32767.5'::SMALLINT;
----
Conversion Error
statement error
select '2147483647.5'::INTEGER;
----
Conversion Error
statement error
select '9223372036854775807.5'::BIGINT;
----
Conversion Error
statement error
select '170141183460469231731687303715884105727.5'::HUGEINT;
----
Conversion Error
statement error
select '-128.5'::TINYINT;
----
Conversion Error
statement error
select '-32768.5'::SMALLINT;
----
Conversion Error
statement error
select '-2147483648.5'::INTEGER;
----
Conversion Error
statement error
select '-9223372036854775808.5'::BIGINT;
----
Conversion Error
statement error
select '-170141183460469231731687303715884105728.5'::HUGEINT;
----
Conversion Error
# going above the limit should error (unsigned)
statement error
select '255.5'::UTINYINT;
----
Conversion Error
statement error
select '65535.5'::USMALLINT;
----
Conversion Error
statement error
select '4294967295.5'::UINTEGER;
----
Conversion Error
statement error
select '18446744073709551615.5'::UBIGINT;
----
Conversion Error

View File

@@ -0,0 +1,289 @@
# name: test/sql/cast/string_to_integer_exponent_cast.test
# description: String to Integer casts with Decimals and Exponents
# group: [cast]
statement ok
PRAGMA enable_verification
# Positive numbers (includes unsigned)
foreach type <integral>
# Positive Number - Positive Exponent
query I
select '1e2'::${type};
----
100
query I
select '1.23e2'::${type};
----
123
query I
select '1.234e2'::${type};
----
123
query I
select '1.235e2'::${type};
----
124
# Positive Number - Negative Exponent
query I
select '1e-2'::${type};
----
0
query I
select '123.456e-2'::${type};
----
1
query I
select '1584.92e-2'::${type};
----
16
query I
select '1214.235e-2'::${type};
----
12
# Out of range
statement error
select '10e40'::${type};
----
Conversion Error
endloop
# Negative numbers (excludes unsigned)
foreach type <signed>
# Negative Number - Positive Exponent
query I
select '-1e2'::${type};
----
-100
query I
select '-1.23456e2'::${type};
----
-123
query I
select '-0.158492e2'::${type};
----
-16
query I
select '-1.235e2'::${type};
----
-124
# Negative Number - Negative Exponent
query I
select '-100e-2'::${type};
----
-1
query I
select '-50.23456e-2'::${type};
----
-1
query I
select '-1584.92e-2'::${type};
----
-16
query I
select '-1.235e-2'::${type};
----
0
statement error
select '-10e40'::${type};
----
Conversion Error
endloop
# Check limits (signed)
query II
select '12.7e1'::TINYINT, '-12.8e1'::TINYINT;
----
127 -128
query II
select '3276.7e1'::SMALLINT, '-3276.8e1'::SMALLINT;
----
32767 -32768
query II
select '214748364.7e1'::INTEGER, '-214748364.8e1'::INTEGER;
----
2147483647 -2147483648
query II
select '922337203685477580.7e1'::BIGINT, '-922337203685477580.8e1'::BIGINT;
----
9223372036854775807 -9223372036854775808
query II
select '17014118346046923173168730371588410572.7e1'::HUGEINT, '-17014118346046923173168730371588410572.8e1'::HUGEINT;
----
170141183460469231731687303715884105727 -170141183460469231731687303715884105728
# Check limits (unsigned)
query I
select '25.5e1'::UTINYINT;
----
255
query I
select '6553.5e1'::USMALLINT;
----
65535
query I
select '429496729.5e1'::UINTEGER;
----
4294967295
query I
select '1844674407370955161.5e1'::UBIGINT;
----
18446744073709551615
query I
select '34028236692093846346337460743176821145.5e1'::UHUGEINT;
----
340282366920938463463374607431768211455
# going over limit should error (signed)
statement error
select '12.8e1'::TINYINT;
----
Conversion Error
statement error
select '3276.8e1'::SMALLINT;
----
Conversion Error
statement error
select '214748364.8e1'::INTEGER;
----
Conversion Error
statement error
select '922337203685477580.8e1'::BIGINT;
----
Conversion Error
statement error
select '17014118346046923173168730371588410572.8e1'::HUGEINT;
----
Conversion Error
statement error
select '-12.9e1'::TINYINT;
----
Conversion Error
statement error
select '-3276.9e1'::SMALLINT;
----
Conversion Error
statement error
select '-214748364.9e1'::INTEGER;
----
Conversion Error
statement error
select '-922337203685477580.9e1'::BIGINT;
----
Conversion Error
statement error
select '-17014118346046923173168730371588410572.9e1'::HUGEINT;
----
Conversion Error
# going over limit should error (unsigned)
statement error
select '25.6e1'::UTINYINT;
----
Conversion Error
statement error
select '6553.6e1'::USMALLINT;
----
Conversion Error
statement error
select '429496729.6e1'::UINTEGER;
----
Conversion Error
statement error
select '1844674407370955161.6e1'::UBIGINT;
----
Conversion Error
# exponent limit
statement error
select '1e100000'::int;
----
Conversion Error
statement error
select '1e-100000'::int;
----
Conversion Error
# some more "extreme" cases
query I
select '0.00000000000000000000000000000009223372036854775807e50'::BIGINT;
----
9223372036854775807
query I
select '-0.00000000000000000000000000000009223372036854775807e50'::BIGINT;
----
-9223372036854775807
query I
select '0.00000000000170141183460469231731687303715884105727e50'::HUGEINT;
----
170141183460469231731687303715884105727
query I
select '-0.00000000000170141183460469231731687303715884105727e50'::HUGEINT;
----
-170141183460469231731687303715884105727
query I
select '15123456789e-32768'::int;
----
0
query I
select '0e32767'::int;
----
0

View File

@@ -0,0 +1,536 @@
# name: test/sql/cast/string_to_list_cast.test
# description: cast strings into (nested) list structures
# group: [cast]
statement ok
PRAGMA enable_verification
# Basic tests:
# ---------------------------------------------------
query I
SELECT '[12,13,14]'::INT[];
----
[12, 13, 14]
query I
SELECT '["hello", "world", "!"]'::VARCHAR[];
----
[hello, world, !]
query I
SELECT CAST('[Hello World!]' AS VARCHAR[]);
----
[Hello World!]
query I
SELECT CAST('[[Hello World!], hello, universe]' AS VARCHAR[]);
----
['[Hello World!]', hello, universe]
query I
SELECT '[Cast like this]':: VARCHAR[];
----
[Cast like this]
# Issue 8797
query I
select UNNEST('[NULL, , NULL]'::varchar[]);
----
NULL
(empty)
NULL
query I
select UNNEST('[NULL,, NULL]'::varchar[]);
----
NULL
(empty)
NULL
query I
select UNNEST('[NULL, , NULL]'::varchar[]);
----
NULL
(empty)
NULL
query I
SELECT UNNEST('[NULL, NULL , ]'::varchar[]);
----
NULL
NULL
(empty)
query I
SELECT UNNEST('[NULL, NULL ,]'::varchar[]);
----
NULL
NULL
(empty)
query I
SELECT UNNEST('[NULL, NULL,]'::varchar[]);
----
NULL
NULL
(empty)
# Nested lists
# ---------------------------------------------------
query III
SELECT CAST('[ [12,13,14], [8, 9], [4], [2, 1, 0] ]' AS INT[][]) a, a::VARCHAR::INT[][] b, a == b;
----
[[12, 13, 14], [8, 9], [4], [2, 1, 0]] [[12, 13, 14], [8, 9], [4], [2, 1, 0]] true
query I
SELECT CAST('[ [[12,13,14], [8, 9]], [[4]], [[2, 1, 0], [99]] ]' AS INT[][][]);
----
[[[12, 13, 14], [8, 9]], [[4]], [[2, 1, 0], [99]]]
query I
SELECT CAST('[ [12,13,14], [8, 9], [4], [2, 1, 0] ]' AS VARCHAR[]);
----
['[12,13,14]', '[8, 9]', '[4]', '[2, 1, 0]']
query I
SELECT CAST('[[ [🦆, 🦆, 🦆]], [[duck, db, 🦆], [🦆]], [[🦆, duck, db]]]' AS VARCHAR[][][]);
----
[[[🦆, 🦆, 🦆]], [[duck, db, 🦆], [🦆]], [[🦆, duck, db]]]
# Cast from table
# ---------------------------------------------------
statement ok
CREATE TABLE stringList (col1 VARCHAR)
statement ok
INSERT INTO stringList VALUES ('["hello","world","!"]'), ('["Amazing","text"]'), ('[Hello World!]');
query I
SELECT col1::VARCHAR[] FROM stringList;
----
[hello, world, !]
[Amazing, text]
[Hello World!]
# ---------------------------------------------------
statement ok
CREATE TABLE nestedStrings (col1 VARCHAR)
statement ok
INSERT INTO nestedStrings VALUES ('[["hello"], ["world"],["!"]]'), ('[["Amazing"],["text"]]'), ('[[Hello World!]]');
query I
SELECT col1::VARCHAR[][] FROM nestedStrings;
----
[[hello], [world], [!]]
[[Amazing], [text]]
[[Hello World!]]
# ---------------------------------------------------
statement ok
CREATE TABLE superNestedStrings (col1 VARCHAR)
statement ok
INSERT INTO superNestedStrings VALUES ('[[[[["hello"]]], [[["world"],["!"]]]]]'), ('[[[[["Amazing"]],[["text"]]]]]'), ('[[[[[Hello World!]]]]]');
query I
SELECT col1::VARCHAR[][][][][] FROM superNestedStrings;
----
[[[[[hello]]], [[[world], [!]]]]]
[[[[[Amazing]], [[text]]]]]
[[[[[Hello World!]]]]]
# ---------------------------------------------------
statement ok
CREATE TABLE tbl (col1 VARCHAR);
statement ok
INSERT INTO tbl VALUES ('[1,2,2]'), ('[345,67865,44,4]'), ('[5,6,7]');
query I
SELECT col1::INT[] FROM tbl;
----
[1, 2, 2]
[345, 67865, 44, 4]
[5, 6, 7]
# ---------------------------------------------------
statement ok
CREATE TABLE doubleNested (col1 VARCHAR);
statement ok
INSERT INTO doubleNested VALUES ('[[1,2],[2]]'), ('[[345],[67865,44,4]]'), ('[[5],[6,7]]');
query I
SELECT col1::INT[][] FROM doubleNested;
----
[[1, 2], [2]]
[[345], [67865, 44, 4]]
[[5], [6, 7]]
# ---------------------------------------------------
statement ok
CREATE TABLE tripleNested (col1 VARCHAR)
statement ok
INSERT INTO tripleNested VALUES ('[[[1,2],[3]]]'), ('[[[4]]]');
query I
SELECT col1::INT[][][] FROM tripleNested;
----
[[[1, 2], [3]]]
[[[4]]]
# ---------------------------------------------------
statement ok
CREATE TABLE crazyNested (col1 VARCHAR)
statement ok
INSERT INTO crazyNested VALUES ('[[[[[[1]],[[3,4,9]]],[[[0,1]]]]]]'), ('[[[[[[4]]]]]]');
query I
SELECT col1::INT[][][][][][] FROM crazyNested;
----
[[[[[[1]], [[3, 4, 9]]], [[[0, 1]]]]]]
[[[[[[4]]]]]]
# Quote handling
# ---------------------------------------------------
query I
SELECT CAST($$['hello','world', '!']$$ AS VARCHAR[]);
----
[hello, world, !]
query I
SELECT CAST($$[\'hello\',\'world\', \'!\']$$ AS VARCHAR[]);
----
['\'hello\'', '\'world\'', '\'!\'']
query I
SELECT CAST($$[[ ['🦆, 🦆, 🦆']], [[duck, db, '🦆'] ]]$$ AS VARCHAR[][][]);
----
[[['🦆, 🦆, 🦆']], [[duck, db, 🦆]]]
query I
SELECT CAST($$[can\'t, you\'re, i\'m]$$ AS VARCHAR[]);
----
['can\'t', 'you\'re', 'i\'m']
query I
SELECT CAST($$["]", "hello", "world"]$$ AS VARCHAR[]);
----
[']', hello, world]
query I
SELECT CAST($$[']', "hello", "world"]$$ AS VARCHAR[]);
----
[']', hello, world]
# Test for whitespaces
# ---------------------------------------------------
query I
SELECT CAST('[ [12, 13,14], [8, 9 ], [ 4 ], [ 2, 1, 0] ] ' AS INT[][]);
----
[[12, 13, 14], [8, 9], [4], [2, 1, 0]]
query I
SELECT CAST('[ [ [12, 13,14], [8, 9 ] ],[[ 4 ] ], [[ 2, 1, 0 ] ] ] ' AS INT[][][]);
----
[[[12, 13, 14], [8, 9]], [[4]], [[2, 1, 0]]]
query I
SELECT CAST($$[" hello"," \"' world", "! "]$$ AS VARCHAR[]);
----
[' hello', ' "\' world', '! ']
query I
SELECT CAST('[ hello , world , ! ]' AS VARCHAR[]);
----
[hello, world, !]
query I
SELECT CAST($$[ [ " hello"] ,[" world" ],[ "! " ] ]$$ AS VARCHAR[][]);
----
[[' hello'], [' world'], ['! ']]
# Empty list
# ---------------------------------------------------
query I
SELECT '[]'::VARCHAR[];
----
[]
query I
SELECT '[]'::INT[];
----
[]
query I
SELECT '[]'::INT[][][][];
----
[]
query I
SELECT '[[1, 2, 3], [], [ ], [ ]]'::INT[][];
----
[[1, 2, 3], [], [], []]
query I
SELECT '[[1, 2, 3], [], NULL, [NULL], [4, NULL]]'::INT[][];
----
[[1, 2, 3], [], NULL, [NULL], [4, NULL]]
# NULL values
# ------------------------------67---------------------
statement ok
CREATE TABLE null_tbl(col1 VARCHAR);
statement ok
INSERT INTO null_tbl VALUES(NULL), (NULL), ('[NULL]');
query I
SELECT col1::INT[] FROM null_tbl;
----
NULL
NULL
[NULL]
query I
SELECT CAST(NULL AS INT[]);
----
NULL
query I
SELECT CAST('[NULL]' AS INT[]);
----
[NULL]
query I
SELECT CAST('[NULL]' AS INT[][]);
----
[NULL]
query I
SELECT CAST('[[12,13,14], [8, 9], NULL, [2, 1]]' AS INT[][]);
----
[[12, 13, 14], [8, 9], NULL, [2, 1]]
query I
SELECT CAST('[[12,13,14], [8, 9], [2, NULL, 1]]' AS INT[][]);
----
[[12, 13, 14], [8, 9], [2, NULL, 1]]
query I
SELECT CAST('[ [[12,13,14], NULL], [[4]], NULL, [[2, NULL, 1, 0], [99]] ]' AS INT[][][]);
----
[[[12, 13, 14], NULL], [[4]], NULL, [[2, NULL, 1, 0], [99]]]
# Try Cast
# ---------------------------------------------------
query I
SELECT TRY_CAST('Hello World' AS INT[]);
----
NULL
statement ok
CREATE TABLE try_cast_tbl (col1 VARCHAR);
statement ok
INSERT INTO try_cast_tbl VALUES ('[1,2,X,2]'), ('[hello DuckDB]'), ('[345,oops,44,4.0]'), ('[12345678901]'), ('[5,6,7]'), ('[3 0, 1]');
query I
SELECT TRY_CAST(col1 AS INT[]) FROM try_cast_tbl;
----
[1, 2, NULL, 2]
[NULL]
[345, NULL, 44, 4]
[NULL]
[5, 6, 7]
[NULL, 1]
# Syntax error checking
# ---------------------------------------------------
statement error
SELECT CAST('{[3]}' AS INT[]);
----
statement error
SELECT CAST('Hello World' AS INT[]);
----
statement error
SELECT CAST('[3]]' AS INT[]);
----
statement error
SELECT CAST('[3],[[]' AS INT[][]);
----
statement error
SELECT CAST('[3], [[1]]' AS INT[][]);
----
statement error
SELECT CAST('[[3 1]]' AS INT[][]);
----
statement error
SELECT CAST('[[3,, 1]]' AS INT[][]);
----
statement error
SELECT CAST('[[3], [[5], [4]]' AS INT[][]);
----
statement error
SELECT CAST('][3]' AS INT[]);
----
statement error
SELECT CAST('[[[[[]][3][[]][][[[][]]]]]' AS INT[][][][]);
----
# Test WHERE clause
# ---------------------------------------------------
query I
SELECT * FROM tbl WHERE cast(col1 as int[]) = [1, 2, 2];
----
[1,2,2]
query I
SELECT col1 FROM tbl WHERE LEN(cast(col1 as int[])) < 4;
----
[1,2,2]
[5,6,7]
query I
SELECT cast(col1 as int[]) FROM tbl WHERE LEN(cast(col1 as int[])) < 4;
----
[1, 2, 2]
[5, 6, 7]
# Lists of structs:
# ---------------------------------------------------
statement ok
CREATE TABLE struct_tbl1(col VARCHAR);
statement ok
INSERT INTO struct_tbl1 VALUES('[{a: "hii"}, {a: "hellooo"}]');
query I
SELECT col::STRUCT(a VARCHAR)[] FROM struct_tbl1;
----
[{'a': hii}, {'a': hellooo}]
query I
SELECT CAST('[ [{a:[12,13,14], b:"🦆"}], [{a:[12,13,14], b:"🦆", c:100}] ]' AS STRUCT(a INT[], b VARCHAR, c FLOAT)[][]);
----
[[{'a': [12, 13, 14], 'b': 🦆, 'c': NULL}], [{'a': [12, 13, 14], 'b': 🦆, 'c': 100.0}]]
query I
SELECT CAST('[{a:[12,13,14], b:"🦆", c:{a:[[a], [b, c]], b:[123]}}]' AS STRUCT(a INT[], b VARCHAR, c STRUCT(a VARCHAR[][], b INT[]))[]);
----
[{'a': [12, 13, 14], 'b': 🦆, 'c': {'a': [[a], [b, c]], 'b': [123]}}]
query I
SELECT '[{a: hii}, {a: "{" }]'::STRUCT(a VARCHAR)[] FROM struct_tbl1;
----
[{'a': hii}, {'a': '{'}]
# ---------------------------------------------------
statement ok
CREATE TABLE struct_tbl2(col VARCHAR);
statement ok
INSERT INTO struct_tbl2 VALUES('[{a: 7, b:"Duck"}, {a: 7000, b: "🦆🦆🦆🦆🦆🦆"}]');
query I
SELECT col::STRUCT(a INT, b VARCHAR)[] FROM struct_tbl2;
----
[{'a': 7, 'b': Duck}, {'a': 7000, 'b': 🦆🦆🦆🦆🦆🦆}]
# CSV reader
# ---------------------------------------------------
statement ok
CREATE TABLE int_list(col INT[]);
statement ok
COPY (SELECT [1,2,3]) TO '__TEST_DIR__/int_list.csv';
statement ok
COPY int_list FROM '__TEST_DIR__/int_list.csv';
query I
SELECT col FROM int_list;
----
[1, 2, 3]
statement ok
CREATE TABLE assorted_lists(col1 INT[], col2 VARCHAR[], col3 DATE[]);
statement ok
COPY (SELECT [8,7,6], $$[hello, Duck\\'DB]$$, '[2022-12-2, 1929-01-25]') TO '__TEST_DIR__/assorted_lists.csv' (Header 0);
statement ok
COPY assorted_lists FROM '__TEST_DIR__/assorted_lists.csv' (ESCAPE '\');
query III
SELECT * FROM assorted_lists;
----
[8, 7, 6] [hello, 'Duck\'DB'] [2022-12-02, 1929-01-25]
# Escape tests
#---------------------------------------------------
# regular escape
# FIXME: this is weird behavior
query I
select '[{"bar":"\""}]'::VARCHAR[];
----
['{"bar":"\\""}']
statement error
select '[{"bar":"\\""}]'::VARCHAR[];
----
# Unescaped doublequote ends the quote early, leaving an uneven amount of `"`, causing an error
statement error
select '[{"bar":"\\""}]'::STRUCT(bar VARCHAR)[];
----
can't be cast to the destination type STRUCT(bar VARCHAR)[]
# uneven amount of escapes does escape the "
query I
select '[{"bar":"\\\""}]'::STRUCT(bar VARCHAR)[];
----
[{'bar': '\\"'}]
# all are escaped except for the last one
query III
select '[{"bar":"\"\"\\\"\"\"\\"}]'::STRUCT(bar VARCHAR)[] a, CAST(a::VARCHAR AS STRUCT(bar VARCHAR)[]) b, a == b;
----
[{'bar': '""\\"""\\'}] [{'bar': '""\\"""\\'}] true
query III
select $$[\ \\abc\\ \ , def, ghi]$$::VARCHAR[] a, a[1], len(a[1])
----
[\ \\abc\\ \, def, ghi] \ \\abc\\ \ 12
query III
select $$["\ \\abc\\ \ ", def, ghi]$$::VARCHAR[] a, a[1], len(a[1])
----
[' \\abc\\ ', def, ghi] \abc\ 9

View File

@@ -0,0 +1,259 @@
# name: test/sql/cast/string_to_list_escapes.test
# group: [cast]
query I
SELECT $$[hello, world]$$::VARCHAR[];
----
[hello, world]
query I
SELECT $$["hello\ world", world]$$::VARCHAR[];
----
[hello world, world]
query I
SELECT $$[hello\ world, world]$$::VARCHAR[];
----
[hello\ world, world]
query I
SELECT $$[hello\,world, test]$$::VARCHAR[];
----
[hello\, world, test]
query I
SELECT $$["hello\,world", test]$$::VARCHAR[];
----
['hello,world', test]
query I
SELECT $$["hello\,", test]$$::VARCHAR[];
----
['hello,', test]
query I
SELECT $$[hello\,, test]$$::VARCHAR[];
----
[hello\, '', test]
query III
SELECT $$['']$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b;
----
[''] [''] true
query I
SELECT $$[hello\"quoted\"text, more]$$::VARCHAR[];
----
['hello"quoted"text', more]
# Not actually an escaped backslash, not wrapped in quotes
query I
SELECT $$[escaped\\backslash, test]$$::VARCHAR[];
----
[escaped\\backslash, test]
query I
SELECT $$["escaped\\backslash", test]$$::VARCHAR[];
----
[escaped\backslash, test]
query I
SELECT $$[nested[brackets], test]$$::VARCHAR[];
----
['nested[brackets]', test]
statement error
SELECT $$[nested[bracket, test]$$::VARCHAR[];
----
can't be cast to the destination type VARCHAR[]
query I
SELECT $$[nested"["bracket, test]$$::VARCHAR[];
----
['nested[bracket', test]
query I
SELECT $$[quote\'in\'string, test]$$::VARCHAR[];
----
['quote\'in\'string', test]
query I
SELECT $$[mix\ of\ special\,chars]$$::VARCHAR[];
----
[mix\ of\ special\, chars]
query I
SELECT $$["mix\ of\ special\,chars"]$$::VARCHAR[];
----
['mix of special,chars']
query I
SELECT $$["mix\ of\ special\,"chars]$$::VARCHAR[];
----
['mix of special,chars']
query I
SELECT $$["ends with space ", "trailing space "]$$::VARCHAR[];
----
['ends with space ', 'trailing space ']
query I
SELECT $$["ends with comma,", "another,"]$$::VARCHAR[];
----
['ends with comma,', 'another,']
query I
SELECT $$["quote at end\"", "\""]$$::VARCHAR[];
----
['quote at end"', '"']
query I
SELECT $$["ends with bracket]", "[bracket"]$$::VARCHAR[];
----
['ends with bracket]', '[bracket']
query I
SELECT $$["backslash at end\\", "\\"]$$::VARCHAR[];
----
[backslash at end\, \]
query I
SELECT $$[" space at start", " leading space"]$$::VARCHAR[];
----
[' space at start', ' leading space']
query I
SELECT $$[",comma at start", ",leading comma"]$$::VARCHAR[];
----
[',comma at start', ',leading comma']
query I
SELECT $$["\"quote at start", "\"leading quote"]$$::VARCHAR[];
----
['"quote at start', '"leading quote']
query I
SELECT $$["[bracket at start", "[leading bracket"]$$::VARCHAR[];
----
['[bracket at start', '[leading bracket']
query I
SELECT $$["\\backslash at start", "\\leading backslash"]$$::VARCHAR[];
----
[\backslash at start, \leading backslash]
query I
SELECT $$[" space at start and end ", " leading and trailing space "]$$::VARCHAR[];
----
[' space at start and end ', ' leading and trailing space ']
query I
SELECT $$[",comma at start and end,", ",leading and trailing comma,"]$$::VARCHAR[];
----
[',comma at start and end,', ',leading and trailing comma,']
query I
SELECT $$["\"quote at start and end\"", "\"leading and trailing quote\""]$$::VARCHAR[];
----
['"quote at start and end"', '"leading and trailing quote"']
query I
SELECT $$["[bracket at start and end]", "[leading and trailing bracket]"]$$::VARCHAR[];
----
['[bracket at start and end]', '[leading and trailing bracket]']
query I
SELECT $$["\\backslash at start and end\\", "\\leading and trailing backslash\\"]$$::VARCHAR[];
----
[\backslash at start and end\, \leading and trailing backslash\]
query I
SELECT $$[" mix, of special\ characters " , "[various] \"combinations\" "]$$::VARCHAR[];
----
[' mix, of special characters ', '[various] "combinations" ']
query I
SELECT $$[", starts and ends with ,", "[brackets] and ,commas,"]$$::VARCHAR[];
----
[', starts and ends with ,', '[brackets] and ,commas,']
query I
SELECT $$["\"quotes\" and \ spaces ", "\ leading and trailing \ "]$$::VARCHAR[];
----
['"quotes" and spaces ', ' leading and trailing ']
query I
SELECT $$["[complex\ combination, of\" special]", "\\all cases covered\\"]$$::VARCHAR[];
----
['[complex combination, of" special]', \all cases covered\]
query I
SELECT $$["hello, world"]$$::VARCHAR[];
----
['hello, world']
statement error
SELECT $$["missing quote]]$$::VARCHAR[]; -- Mismatched quotes
----
can't be cast to the destination type
statement error
SELECT $$["backslash at end\"]$$::VARCHAR[]; -- Improper escaping
----
can't be cast to the destination type
statement error
SELECT $$[unescaped[bracket]$$::VARCHAR[]; -- Unescaped bracket
----
can't be cast to the destination type
statement error
SELECT $$[unterminated string]"]$$::VARCHAR[];
----
can't be cast to the destination type
query I
SELECT $$[]$$::VARCHAR[]; -- Empty list
----
[]
query I
SELECT $$[""]$$::VARCHAR[]; -- List with empty string
----
['']
query I
SELECT $$[" "]$$::VARCHAR[]; -- List with whitespace string
----
[' ']
query I
SELECT $$["\\"]$$::VARCHAR[]; -- List with only a backslash
----
[\]
query I
SELECT $$["\""]$$::VARCHAR[]; -- List with only a quote
----
['"']
query I
SELECT $$[\,]$$::VARCHAR[]; -- List with only a comma (not quoted)
----
[\, '']
query I
SELECT $$["\,"]$$::VARCHAR[]; -- List with only a comma
----
[',']
query I
SELECT $$[","]$$::VARCHAR[]; -- List with only a comma
----
[',']
query III
select $$[NULL, 'null', 'nUlL', NuLl, "NULLz", "NULL"]$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b
----
[NULL, 'null', 'nUlL', NULL, NULLz, 'NULL'] [NULL, 'null', 'nUlL', NULL, NULLz, 'NULL'] true

View File

@@ -0,0 +1,39 @@
# name: test/sql/cast/string_to_list_roundtrip.test
# group: [cast]
query III
select $$[\"abc\", def, ghi]$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b
----
['"abc"', def, ghi] ['"abc"', def, ghi] true
statement ok
COPY (select $$[\"abc\", def, ghi]$$::VARCHAR[] a) TO '__TEST_DIR__/copy_test.csv' (FORMAT CSV);
query II
select a, a::VARCHAR[] from read_csv('__TEST_DIR__/copy_test.csv') t(a);
----
['"abc"', def, ghi] ['"abc"', def, ghi]
# Leading and trailing whitespace preservation
query III
select $$[" \"abc\" ", def, ghi]$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b
----
[' "abc" ', def, ghi] [' "abc" ', def, ghi] true
# Escaping backslashes
query III
select $$[\ \\abc\\ \ , def, ghi]$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b
----
[\ \\abc\\ \, def, ghi] [\ \\abc\\ \, def, ghi] true
# Escaping backslashes
query III
select $$["\ \\abc\\ \ ", def, ghi]$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b
----
[' \\abc\\ ', def, ghi] [' \\abc\\ ', def, ghi] true
# Escaping '{' and '}'
query III
select $$[{}]$$::VARCHAR[] a, a::VARCHAR::VARCHAR[] b, a == b
----
['{}'] ['{}'] true

View File

@@ -0,0 +1,334 @@
# name: test/sql/cast/string_to_map_cast.test_slow
# description: cast strings into map structures
# group: [cast]
statement ok
PRAGMA enable_verification
# Basic tests:
# ---------------------------------------------------
query I
SELECT '{a=1, b=2, c=3}'::MAP(VARCHAR, INT)
----
{a=1, b=2, c=3}
query I
SELECT '{key_A=Duck, key_B="hello world"}'::MAP(VARCHAR, VARCHAR)
----
{key_A=Duck, key_B=hello world}
query I
SELECT '{1=Duck, 2=hello world, 3=!}'::MAP(INT, VARCHAR)
----
{1=Duck, 2=hello world, 3=!}
query I
SELECT '{greetings=[Hello World!, Hello DuckDB, Howdy], farewells=[Bye World, Bye DuckDB]}'::MAP(VARCHAR, VARCHAR[]);
----
{greetings=[Hello World!, Hello DuckDB, Howdy], farewells=[Bye World, Bye DuckDB]}
query I
SELECT '{"key=A"=Duck, "key=B"="hello=world"}'::MAP(VARCHAR, VARCHAR)
----
{'key=A'=Duck, 'key=B'='hello=world'}
statement error
SELECT '{a=1, b=2, a=3}'::MAP(VARCHAR, INT)
----
Map keys must be unique
# Nested Maps
# ---------------------------------------------------
query I
SELECT '{{1=100, 2=200}=value}'::MAP(MAP(INT, INT), VARCHAR);
----
{{1=100, 2=200}=value}
query I
SELECT '{{1=100, 2=200}={3=c, 5=e, 7=g}}'::MAP(MAP(INT, INT), MAP(INT, VARCHAR));
----
{{1=100, 2=200}={3=c, 5=e, 7=g}}
# Cast from table
# ---------------------------------------------------
statement ok
CREATE TABLE stringMap (col1 VARCHAR)
statement ok
INSERT INTO stringMap VALUES ('{1=Duck, 2=DB}'), ('{999=🦆}'), ('{7=Hello, 8=World, 2=!}');
query I
SELECT col1::MAP(INT, VARCHAR) FROM stringMap;
----
{1=Duck, 2=DB}
{999=🦆}
{7=Hello, 8=World, 2=!}
# Quote escaping
# ---------------------------------------------------
query I
SELECT CAST('{''hello''=2, ''world''=50, ''!''=12}' AS MAP(VARCHAR, INT));
----
{hello=2, world=50, !=12}
query I
SELECT CAST($${\'hello\'=hello, \'world\'=world, \'!\'=!}$$ AS MAP(VARCHAR, VARCHAR));
----
{'\'hello\''=hello, '\'world\''=world, '\'!\''=!}
query I
SELECT CAST($${[[\'🦆, 🦆, 🦆\']]=100, [[duck, db, \'🦆\']]=101}$$ AS MAP(VARCHAR[][], INT));
----
{[['\'🦆', 🦆, '🦆\'']]=100, [[duck, db, '\'🦆\'']]=101}
query I
SELECT CAST($${"can't"="you're", "i'm"="q'u'o't'e"}$$ AS MAP(VARCHAR, VARCHAR));
----
{'can\'t'='you\'re', 'i\'m'='q\'u\'o\'t\'e'}
query III
SELECT CAST('{"{"="}", "["="]"}' AS MAP(VARCHAR, VARCHAR)) a, a::VARCHAR::MAP(VARCHAR, VARCHAR) b, a == b;
----
{'{'='}', '['=']'} {'{'='}', '['=']'} true
query III
SELECT CAST($${'}'="{", ']'="["}$$ AS MAP(VARCHAR, VARCHAR)) a, a::VARCHAR::MAP(VARCHAR, VARCHAR) b, a == b;
----
{'}'='{', ']'='['} {'}'='{', ']'='['} true
# Test for whitespaces
# ---------------------------------------------------
query I
SELECT ' {greetings =[ Hello World !, Hello DuckDB , Howdy ] , farewells= [Bye World, Bye DuckDB ] } '::MAP(VARCHAR, VARCHAR[]);
----
{greetings=[Hello World !, Hello DuckDB, Howdy], farewells=[Bye World, Bye DuckDB]}
query I
SELECT CAST('{ [12, 13,14]=val, [ 8, 9 ] =val, [ 4 ]=val }' AS MAP(INT[], VARCHAR));
----
{[12, 13, 14]=val, [8, 9]=val, [4]=val}
query I
SELECT CAST($$ { { a:[2, 3], b: Duckster }= {50.0 =50}, {a : [9,1,4], b:Duck }
={ 1 = 0} }$$ AS MAP(STRUCT(a INT[], b VARCHAR), MAP(INT, DOUBLE)));
----
{{'a': [2, 3], 'b': Duckster}={50=50.0}, {'a': [9, 1, 4], 'b': Duck}={1=0.0}}
# NULL values
# ---------------------------------------------------
statement ok
CREATE TABLE null_tbl(col1 VARCHAR);
statement ok
INSERT INTO null_tbl VALUES(NULL), ('{key=NULL}'), ('{zero=0, key=NULL}');
query I
SELECT col1::MAP(VARCHAR, VARCHAR) FROM null_tbl;
----
NULL
{key=NULL}
{zero=0, key=NULL}
query I
SELECT CAST(NULL AS MAP(INT, VARCHAR));
----
NULL
query I
SELECT CAST('{12=34, 56=NULL, 910=1112, 1314=NULL}' AS MAP(INT, INT));
----
{12=34, 56=NULL, 910=1112, 1314=NULL}
statement error
SELECT CAST('{NULL=5}' AS MAP(INT, INT));
----
Conversion Error: Type VARCHAR with value '{NULL=5}' can't be cast to the destination type MAP
query I
SELECT CAST('{}' AS MAP(INT, INT));
----
{}
# Try Cast
#---------------------------------------------------
query I
SELECT TRY_CAST('Hello World' AS MAP(VARCHAR, VARCHAR));
----
NULL
statement ok
CREATE TABLE try_cast_tbl (col1 VARCHAR);
statement ok
INSERT INTO try_cast_tbl VALUES ('{1=2, XXX=2}'), ('{NULL=DuckDB}'), ('{3=oops, 5=5 44=4.0}'), ('{12345678901=0}'), ('{5=6!, 7=7000}'), ('{3 0, 1=1}');
query I
SELECT TRY_CAST(col1 AS MAP(INT, INT)) FROM try_cast_tbl;
----
NULL
NULL
{3=NULL, 5=NULL}
NULL
{5=NULL, 7=7000}
NULL
# Syntax error checking
# ---------------------------------------------------
statement error
SELECT CAST('{3==3}' AS MAP(INT, INT));
----
statement error
SELECT CAST('{[5]=5}' AS MAP(INT, INT));
----
statement error
SELECT CAST('{3=three}}' AS MAP(INT, VARCHAR));
----
statement error
SELECT CAST('{Ducky=, DB=ok}' AS MAP(VARCHAR, INT));
----
statement error
SELECT CAST('{5=5,, 3=3}' AS MAP(INT, INT));
----
statement error
SELECT CAST('{3=3, 4=4' AS MAP(INT, INT));
----
statement error
SELECT CAST('{3=3, 4=4} bla' AS MAP(INT, INT));
----
statement error
SELECT CAST('{ ' AS MAP(INT, INT));
----
# Test WHERE clause
# ---------------------------------------------------
statement ok
CREATE TABLE Duck_tbl (col1 VARCHAR);
statement ok
INSERT INTO Duck_tbl VALUES ('{1=Duck, 3=DB}'), ('{12=DuckDB}'), ('{3=DB, 5=🦆 4=Ducky, 7=Duckster}'), ('{0=DuckParty}'), ('{5=DBDuck, 7=Duckster, 1=🦆}'), ('{1="final Quack"}');
query I
SELECT * FROM Duck_tbl WHERE cast(col1 as MAP(INT, VARCHAR))[7] = 'Duckster' ;
----
{3=DB, 5=🦆 4=Ducky, 7=Duckster}
{5=DBDuck, 7=Duckster, 1=🦆}
query I
SELECT col1::MAP(INT, VARCHAR) FROM Duck_tbl WHERE cardinality(cast(col1 as MAP(INT, VARCHAR))) < 3;
----
{1=Duck, 3=DB}
{12=DuckDB}
{0=DuckParty}
{1=final Quack}
# Maps of structs and lists:
# ---------------------------------------------------
query I
SELECT CAST('{A={a:[12,13,14], b:"🦆", c:0.12}, B={a:[12,13,14], b:DuckDuck, c:9.03}}' AS MAP(VARCHAR, STRUCT(a INT[], b VARCHAR, c FLOAT)));
----
{A={'a': [12, 13, 14], 'b': 🦆, 'c': 0.12}, B={'a': [12, 13, 14], 'b': DuckDuck, 'c': 9.03}}
query I
SELECT CAST('{{a:Meow=Meow}={a:12, b:0.8, c:MeowMeow}, {a:Quack}={a:13, b:3.2, c:QuackQuack}}' AS MAP(STRUCT(a VARCHAR), STRUCT(a INT, b DOUBLE, c VARCHAR)));
----
{{'a': 'Meow=Meow'}={'a': 12, 'b': 0.8, 'c': MeowMeow}, {'a': Quack}={'a': 13, 'b': 3.2, 'c': QuackQuack}}
query I
SELECT CAST('{{A:AAA}={a:[12,13,14], b:"🦆", c:{a:[[a], [b, c]], b:[123]}}}' AS MAP(STRUCT(A VARCHAR), STRUCT(a INT[], b VARCHAR, c STRUCT(a VARCHAR[][], b INT[]))));
----
{{'A': AAA}={'a': [12, 13, 14], 'b': 🦆, 'c': {'a': [[a], [b, c]], 'b': [123]}}}
query I
SELECT '{[[a, b], [c, d], [e]]= {a:2000}, [[aaa]]={a:100}, [[z],[y], [x]]={}}'::MAP(VARCHAR[][], STRUCT(a INT));
----
{[[a, b], [c, d], [e]]={'a': 2000}, [[aaa]]={'a': 100}, [[z], [y], [x]]={'a': NULL}}
# All types:
# ---------------------------------------------------
query I
SELECT CAST('{a=True, b=False, z=true, X=FALSE}' AS MAP(VARCHAR, BOOL));
----
{a=true, b=false, z=true, X=false}
query I
SELECT CAST('{True=[true, FALSE, true], False=[false, false, false]}' AS MAP(BOOL, BOOL[]));
----
{true=[true, false, true], false=[false, false, false]}
foreach type TINYINT SMALLINT INTEGER BIGINT HUGEINT UTINYINT USMALLINT UINTEGER UBIGINT UHUGEINT
query I
SELECT CAST('{0={a:1, b: 8.3}, 5.7={a:2, b: 3}}' AS MAP(${type}, STRUCT(a ${type}, b ${type})));
----
{0={'a': 1, 'b': 8}, 6={'a': 2, 'b': 3}}
endloop
foreach type DOUBLE FLOAT
query I
SELECT CAST('{-9.01=9.13 ,3=0.00002}' AS MAP(${type}, ${type}));
----
{-9.01=9.13, 3.0=2e-05}
endloop
statement ok
CREATE TYPE mood AS ENUM('ok', 'sad', 'happy');
query I
SELECT '{🦆=ok, duck=happy}'::MAP(VARCHAR, MOOD)
----
{🦆=ok, duck=happy}
query I
SELECT '{ok=happy, sad=ok}'::MAP(MOOD, MOOD)
----
{ok=happy, sad=ok}
statement error
SELECT '{sadDucky: nothappy}'::MAP(VARCHAR, MOOD)
----
# Larger input test
# ---------------------------------------------------
statement ok
CREATE TABLE intMap AS SELECT map([i], [i+1])::VARCHAR::MAP(INT, INT) col FROM range(0, 10000) tbl(i);
query I
SELECT MAX(CAST(col AS MAP(INT, INT))) FROM intMap;
----
{9999=10000}
# CSV reader
# ---------------------------------------------------
statement ok
CREATE TABLE assembled_maps(col1 MAP(INT, VARCHAR));
statement ok
COPY (SELECT '{8="hello, DuckDB"}') TO '__TEST_DIR__/assembled_maps.csv';
statement ok
COPY assembled_maps FROM '__TEST_DIR__/assembled_maps.csv';
query I
SELECT * FROM assembled_maps;
----
{8='hello, DuckDB'}

View File

@@ -0,0 +1,157 @@
# name: test/sql/cast/string_to_map_escapes.test
# group: [cast]
# Valid: key and value with escaped space
query I
SELECT $${"key\ with\ space" = "value\ with\ space"}$$::MAP(VARCHAR, VARCHAR);
----
{key with space=value with space}
# Valid: key with escaped quote and value with escaped quote
query I
SELECT $${\"key\" = \"value\"}$$::MAP(VARCHAR, VARCHAR);
----
{'"key"'='"value"'}
# Valid: key with escaped backslash, value with escaped backslash
query I
SELECT $${"key\ with\ backslash" = "value\ with\ backslash"}$$::MAP(VARCHAR, VARCHAR);
----
{key with backslash=value with backslash}
# Valid: key with escaped comma, value with escaped comma
query I
SELECT $${"key\ with\, comma" = "value\ with\, comma"}$$::MAP(VARCHAR, VARCHAR);
----
{'key with, comma'='value with, comma'}
# Valid: key and value with escaped colon
query I
SELECT $${"key\ with\ colon\:" = "value\ with\ colon\:"}$$::MAP(VARCHAR, VARCHAR);
----
{'key with colon:'='value with colon:'}
## FIXME: not sure what to do here, maybe we shouldn't "respect scopes" if the child type is not nested
## Valid: key and value with parentheses
#query I
#SELECT $${key\ (with\ parens) = value\ (with\ parens)}$$::MAP(VARCHAR, VARCHAR);
#----
#{key (with parens)=value (with parens)}
# Valid: key contains unescaped space
query I
SELECT $${key with space = value with space}$$::MAP(VARCHAR, VARCHAR);
----
{key with space=value with space}
# Invalid: key input contains quotes
query I
SELECT $${key"with"quote = value}$$::MAP(VARCHAR, VARCHAR);
----
{keywithquote=value}
# Valid: value input contains quotes
query I
SELECT $${key = value"with"quote}$$::MAP(VARCHAR, VARCHAR);
----
{key=valuewithquote}
# Valid: key contains unescaped comma
query I
SELECT $${key,with,comma = value}$$::MAP(VARCHAR, VARCHAR);
----
{'key,with,comma'=value}
# Invalid: value contains unescaped comma
statement error
SELECT $${key = value,with,comma}$$::MAP(VARCHAR, VARCHAR);
----
can't be cast to the destination type MAP
# Valid: key contains unescaped curly bracket
query I
SELECT $${key{with}bracket = value}$$::MAP(VARCHAR, VARCHAR);
----
{'key{with}bracket'=value}
# Invalid: value contains unescaped curly bracket
query I
SELECT $${key = value{with}bracket}$$::MAP(VARCHAR, VARCHAR);
----
{key='value{with}bracket'}
# Valid: key contains useless backslashes
query I
SELECT $${"key\with\backslash" = value}$$::MAP(VARCHAR, VARCHAR);
----
{keywithbackslash=value}
# Valid: value contains useless backslashes
query I
SELECT $${key = "value\with\backslash"}$$::MAP(VARCHAR, VARCHAR);
----
{key=valuewithbackslash}
# Valid: key/value contains unescaped equal sign
query II
SELECT $${key=with=equals = value}$$::MAP(VARCHAR, VARCHAR) a, a['key'];
----
{key='with=equals = value'} with=equals = value
# Valid: key/value contains unescaped equal sign
query II
SELECT $${"key\=with" = equals = value}$$::MAP(VARCHAR, VARCHAR) a, a['key=with'];
----
{'key=with'='equals = value'} equals = value
# Valid: key/value contains unescaped equal sign
query II
SELECT $${"key\=with\=equals" = value}$$::MAP(VARCHAR, VARCHAR) a, a['key=with=equals'];
----
{'key=with=equals'=value} value
# Edge Case: Empty MAP with no keys/values
query I
SELECT $${}$$::MAP(VARCHAR, VARCHAR);
----
{}
# Valid: MAP with empty key and value
query I
SELECT $${=}$$::MAP(VARCHAR, VARCHAR);
----
{''=''}
# Edge Case: MAP with special characters only (escaped)
statement error
SELECT $${\{escaped\brace\} = \}escaped\brace\\}$$::MAP(VARCHAR, VARCHAR);
----
can't be cast to the destination type MAP(VARCHAR, VARCHAR)
# Edge Case: MAP with special characters only (escaped)
query I
SELECT $${"\{escaped\brace\}" = "\}escaped\brace\\"}$$::MAP(VARCHAR, VARCHAR);
----
{'{escapedbrace}'='}escapedbrace\\'}
# Edge Case: MAP with only a key and no value
query I
SELECT $${key=}$$::MAP(VARCHAR, VARCHAR);
----
{key=''}
# Valid: MAP with an empty key
query I
SELECT $${=value}$$::MAP(VARCHAR, VARCHAR);
----
{''=value}
query III
select $${'NULL'=true}$$::MAP(VARCHAR, VARCHAR) a, a::VARCHAR::MAP(VARCHAR, VARCHAR) b, a == b
----
{'NULL'=true} {'NULL'=true} true
query III
select $${'a'='NULL'}$$::MAP(VARCHAR, VARCHAR) a, a::VARCHAR::MAP(VARCHAR, VARCHAR) b, a == b
----
{a='NULL'} {a='NULL'} true

View File

@@ -0,0 +1,203 @@
# name: test/sql/cast/string_to_nested_types_cast.test_slow
# description: cast strings into (nested) types
# group: [cast]
statement ok
PRAGMA enable_verification
# These are some slow tests in addition to the string_to_list/struct casting tests
# All types to List cast
# ---------------------------------------------------
query I
SELECT CAST('[[True,False], [true], [FALSE], [false, true]]' AS BOOL[][]);
----
[[true, false], [true], [false], [false, true]]
foreach type INT TINYINT SMALLINT INTEGER BIGINT HUGEINT UTINYINT USMALLINT UINTEGER UBIGINT UHUGEINT
query I
SELECT CAST('[1,2,3]' AS ${type}[]);
----
[1, 2, 3]
endloop
foreach type DOUBLE[] FLOAT[]
query I
SELECT CAST('[[1,2,3], [3.333, 2.2, 1.1], [0]]' AS ${type}[]);
----
[[1.0, 2.0, 3.0], [3.333, 2.2, 1.1], [0.0]]
endloop
statement ok
CREATE TYPE mood AS ENUM('ok', 'sad', 'happy');
query I
SELECT '[ok,happy]'::MOOD[]
----
[ok, happy]
statement error
SELECT '[nothappy]'::MOOD[]
----
query III
SELECT CAST(LIST(date)::VARCHAR AS DATE[]) a, a::VARCHAR::DATE[] b, a == b FROM test_all_types();
----
['5877642-06-25 (BC)', 5881580-07-10, NULL] ['5877642-06-25 (BC)', 5881580-07-10, NULL] true
query I
SELECT CAST(LIST(time)::VARCHAR AS TIME[]) FROM test_all_types();
----
['00:00:00', '24:00:00', NULL]
query I
SELECT CAST(LIST(timestamp)::VARCHAR AS TIME[]) FROM test_all_types();
----
['00:00:00', '04:00:54.775806', NULL]
query I
SELECT CAST(LIST(timestamp_s)::VARCHAR AS TIME[]) FROM test_all_types();
----
['00:00:00', '04:00:54', NULL]
query I
SELECT CAST(LIST(timestamp_ms)::VARCHAR AS TIME[]) FROM test_all_types();
----
['00:00:00', '04:00:54.775', NULL]
query I
SELECT CAST(LIST(timestamp_ns)::VARCHAR AS TIME[]) FROM test_all_types();
----
['00:00:00', '23:47:16.854775', NULL]
query I
SELECT CAST(LIST(blob)::VARCHAR AS BLOB[]) FROM test_all_types();
----
[thisisalongblob\x00withnullbytes, \x00\x00\x00a, NULL]
query I
SELECT CAST(LIST(interval)::VARCHAR AS INTERVAL[]) FROM test_all_types();
----
['00:00:00', '83 years 3 months 999 days 00:16:39.999999', NULL]
# Larger input to List cast
# ---------------------------------------------------
statement ok
CREATE TABLE big_list(col INT[]);
statement ok
COPY (SELECT [i, NULL]::VARCHAR FROM range(0, 2000) tbl(i)) TO '__TEST_DIR__/big_list.csv' (HEADER 0);
statement ok
COPY big_list FROM '__TEST_DIR__/big_list.csv';
query I
SELECT COUNT(col) FROM big_list;
----
2000
# All types to Struct cast:
# ---------------------------------------------------
query I
SELECT CAST('{a: True, b: False, c:[true]}' AS STRUCT(a BOOL, b BOOL, c BOOL[], d STRUCT(a BOOL, b BOOL)));
----
{'a': true, 'b': false, 'c': [true], 'd': NULL}
foreach type INT TINYINT SMALLINT INTEGER BIGINT HUGEINT UTINYINT USMALLINT UINTEGER UBIGINT UHUGEINT
query I
SELECT CAST('{a:1, b:{a:2, b: 3}}' AS STRUCT(a ${type}, b STRUCT(a ${type}, b ${type})));
----
{'a': 1, 'b': {'a': 2, 'b': 3}}
endloop
foreach type DOUBLE FLOAT
query I
SELECT CAST('{a:1, b:{a:2}, c: 0.00002}' AS STRUCT(a ${type}, b STRUCT(a ${type}), c ${type}));
----
{'a': 1.0, 'b': {'a': 2.0}, 'c': 2e-05}
endloop
query I
SELECT '{a: ok, b: happy}'::STRUCT(a MOOD, b MOOD)
----
{'a': ok, 'b': happy}
statement error
SELECT '{a: nothappy}'::STRUCT(a MOOD)
----
query I
SELECT CAST(struct_pack(A=>date)::VARCHAR AS STRUCT(A DATE)) FROM test_all_types();
----
{'A': '5877642-06-25 (BC)'}
{'A': 5881580-07-10}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>time)::VARCHAR AS STRUCT(A TIME)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '24:00:00'}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>timestamp)::VARCHAR AS STRUCT(A TIME)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '04:00:54.775806'}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>timestamp_s)::VARCHAR AS STRUCT(A TIME)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '04:00:54'}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>timestamp_ms)::VARCHAR AS STRUCT(A TIME)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '04:00:54.775'}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>timestamp_ms)::VARCHAR AS STRUCT(A TIME)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '04:00:54.775'}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>timestamp_ns)::VARCHAR AS STRUCT(A TIME)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '23:47:16.854775'}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>blob)::VARCHAR AS STRUCT(A BLOB)) FROM test_all_types();
----
{'A': thisisalongblob\x00withnullbytes}
{'A': \x00\x00\x00a}
{'A': NULL}
query I
SELECT CAST(struct_pack(A=>interval)::VARCHAR AS STRUCT(A INTERVAL)) FROM test_all_types();
----
{'A': '00:00:00'}
{'A': '83 years 3 months 999 days 00:16:39.999999'}
{'A': NULL}

View File

@@ -0,0 +1,485 @@
# name: test/sql/cast/string_to_struct_cast.test
# description: cast strings into (nested) structs
# group: [cast]
statement ok
PRAGMA enable_verification
# Basic tests:
# ---------------------------------------------------
query I
SELECT '{key_A:0}'::STRUCT(key_A INT);
----
{'key_A': 0}
query I
SELECT '{key_A: 2, key_B: 46, key_C: -3000}'::STRUCT(key_A INT, key_B INT, key_C INT);
----
{'key_A': 2, 'key_B': 46, 'key_C': -3000}
query I
SELECT '{key_A: 2, key_B: 3, key_C: 8}'::STRUCT(key_A INT, key_B DOUBLE, key_C FLOAT);
----
{'key_A': 2, 'key_B': 3.0, 'key_C': 8.0}
query I
SELECT '{"key_A": 2, "key_B": hello world}'::STRUCT(key_A INT, key_B VARCHAR);
----
{'key_A': 2, 'key_B': hello world}
query I
select (struct_pack(key_A=>'42'::double, key_B=>'DuckDB'::string)::VARCHAR)::STRUCT(key_A INT, key_B VARCHAR);
----
{'key_A': 42, 'key_B': DuckDB}
query I
SELECT '{🦆: Quack, 🦤: ....}'::STRUCT(🦆 VARCHAR, 🦤 VARCHAR);
----
{'🦆': Quack, '🦤': ....}
# Nested structs
# ---------------------------------------------------
query I
SELECT '{a:{c:1}, b:900}'::STRUCT(a STRUCT(c INT), b INT);
----
{'a': {'c': 1}, 'b': 900}
query I
SELECT '{a:{b:DuckDB, c:12}, b:900, c:{a:"DuckParty"}}'::STRUCT(a STRUCT(b VARCHAR, c INT), b INT, c STRUCT(a VARCHAR));
----
{'a': {'b': DuckDB, 'c': 12}, 'b': 900, 'c': {'a': DuckParty}}
query I
SELECT '{a:{b:DuckDB, c:{a:{a:0.9, b:{a:"DuckieDuck"}, c:{a:9000}, d:{a:5881580-07-10}}, b:"🦆"}}, b:900, c:{a:"DuckParty"}}'::STRUCT(a STRUCT(b VARCHAR, c STRUCT(a STRUCT(a FLOAT, b STRUCT(a VARCHAR), c STRUCT(a INT), d STRUCT(a DATE)), b VARCHAR)), b INT, c STRUCT(a VARCHAR));
----
{'a': {'b': DuckDB, 'c': {'a': {'a': 0.9, 'b': {'a': DuckieDuck}, 'c': {'a': 9000}, 'd': {'a': 5881580-07-10}}, 'b': 🦆}}, 'b': 900, 'c': {'a': DuckParty}}
query I
SELECT CAST('{a:{b:{c:{d:{e:{f:"Hello World"}}}}}}' AS STRUCT(a STRUCT(b STRUCT(c STRUCT(d STRUCT(e STRUCT(f VARCHAR)))))));
----
{'a': {'b': {'c': {'d': {'e': {'f': Hello World}}}}}}
# Cast from table
# ---------------------------------------------------
statement ok
CREATE TABLE tbl1(col VARCHAR);
statement ok
INSERT INTO tbl1 (VALUES ('{a:1, b:3}'));
query I
SELECT col::STRUCT(a INT, b INT) FROM tbl1;
----
{'a': 1, 'b': 3}
# ---------------------------------------------------
statement ok
CREATE TABLE tbl2(col VARCHAR);
statement ok
INSERT INTO tbl2 (VALUES ('{a:1, b:"hello, world"}'));
query III
SELECT col::STRUCT(a INT, b VARCHAR) a, a::VARCHAR::STRUCT(a INT, b VARCHAR) b, a == b FROM tbl2;
----
{'a': 1, 'b': 'hello, world'} {'a': 1, 'b': 'hello, world'} true
# ---------------------------------------------------
statement ok
CREATE TABLE tbl3(col VARCHAR);
statement ok
INSERT INTO tbl3 (VALUES ('{a:DUCK, b:9.999, c:12}'), ('{a:"DB", b:1.111, c:21}'));
query I
SELECT col::STRUCT(a VARCHAR, b FLOAT, c INT) FROM tbl3;
----
{'a': DUCK, 'b': 9.999, 'c': 12}
{'a': DB, 'b': 1.111, 'c': 21}
# ---------------------------------------------------
statement ok
CREATE TABLE tbl4(col VARCHAR);
statement ok
INSERT INTO tbl4 (VALUES ('{a:{b:1}}'));
query I
SELECT col::STRUCT(a STRUCT(b INT)) FROM tbl4;
----
{'a': {'b': 1}}
# Struct with lists
# ---------------------------------------------------
query I
SELECT '{key_A: [2, 3, 4], key_B: [Hello, World]}'::STRUCT(key_A INT[], key_B VARCHAR[]);
----
{'key_A': [2, 3, 4], 'key_B': [Hello, World]}
query I
SELECT '{key_A: [[2, 3], [4]], key_B: [Hello, World]}'::STRUCT(key_A INT[][], key_B VARCHAR[]);
----
{'key_A': [[2, 3], [4]], 'key_B': [Hello, World]}
query I
SELECT '{key_A: [[{a: 5, b: 900}, {a:3, b:34}], [{a:2, b: 0}]], key_B: [Hello, World]}'::STRUCT(key_A STRUCT(a INT, b INT)[][], key_B VARCHAR[]);
----
{'key_A': [[{'a': 5, 'b': 900}, {'a': 3, 'b': 34}], [{'a': 2, 'b': 0}]], 'key_B': [Hello, World]}
# Unordered casting
# ---------------------------------------------------
query I
SELECT '{key_B: 2, key_A: 46}'::STRUCT(key_A INT, key_B INT);
----
{'key_A': 46, 'key_B': 2}
query I
SELECT '{c:{a:"DuckParty"}, b:900, a:{b:DuckDB, c:{a:{a:0.9, b:{a:"DuckieDuck"}, c:{a:9000}, d:{a:5881580-07-10}}, b:"🦆"}}}'::STRUCT(a STRUCT(b VARCHAR, c STRUCT(a STRUCT(a FLOAT, b STRUCT(a VARCHAR), c STRUCT(a INT), d STRUCT(a DATE)), b VARCHAR)), b INT, c STRUCT(a VARCHAR));
----
{'a': {'b': DuckDB, 'c': {'a': {'a': 0.9, 'b': {'a': DuckieDuck}, 'c': {'a': 9000}, 'd': {'a': 5881580-07-10}}, 'b': 🦆}}, 'b': 900, 'c': {'a': DuckParty}}
query I
SELECT '{key_D: "World Hello", key_B: [Hello, World], key_C : 5000, key_A: [[{a: 5, b: 900}, {a:3, b:34}], [{a:2, b: 0}]]}'::STRUCT(key_A STRUCT(a INT, b INT)[][], key_B VARCHAR[], key_C INT, key_D VARCHAR);
----
{'key_A': [[{'a': 5, 'b': 900}, {'a': 3, 'b': 34}], [{'a': 2, 'b': 0}]], 'key_B': [Hello, World], 'key_C': 5000, 'key_D': World Hello}
# Quote escaping
# ---------------------------------------------------
query I
SELECT ($${a: "can't", b: "you're", c: "i'm"}$$::STRUCT(a VARCHAR, b VARCHAR, c VARCHAR));
----
{'a': 'can\'t', 'b': 'you\'re', 'c': 'i\'m'}
query I
SELECT ('{a:"}", b: hello universe}'::STRUCT(a VARCHAR, b VARCHAR));
----
{'a': '}', 'b': hello universe}
query I
SELECT ($${a:'}', b: "hello world"}$$::STRUCT(a VARCHAR, b VARCHAR));
----
{'a': '}', 'b': hello world}
# Test for whitespaces
# ---------------------------------------------------
query I
SELECT '{ key_A: 2, key_B: hello world }'::STRUCT(key_A INT, key_B VARCHAR);
----
{'key_A': 2, 'key_B': hello world}
query I
SELECT ' {a: {b: DuckDB, c:12 }, b: 900, c :{a
: "DuckParty "} } '::STRUCT(a STRUCT(b VARCHAR, c INT), b INT, c STRUCT(a VARCHAR));
----
{'a': {'b': DuckDB, 'c': 12}, 'b': 900, 'c': {'a': 'DuckParty '}}
query I
SELECT '{key_A : [ [{ a: 5 , b : 900 }, { a: 3, b: 34}], [ {a:
2, b: 0 } ] ], key_B: [Hello , World] }'::STRUCT(key_A STRUCT(a INT, b INT)[][], key_B VARCHAR[]);
----
{'key_A': [[{'a': 5, 'b': 900}, {'a': 3, 'b': 34}], [{'a': 2, 'b': 0}]], 'key_B': [Hello, World]}
query I
SELECT '{a : {c : 9000}, b : NULL
, c:{ d: "Ducky", e: NULL } } '::STRUCT(a STRUCT(c INT), b VARCHAR, c STRUCT(d VARCHAR, e DOUBLE));
----
{'a': {'c': 9000}, 'b': NULL, 'c': {'d': Ducky, 'e': NULL}}
query I
SELECT ' { } '::STRUCT(a INT, b DATE);
----
{'a': NULL, 'b': NULL}
statement error
SELECT '{ key_A: 2, key_B: {key_C: hello world } X }'::STRUCT(key_A INT, key_B STRUCT(key_C VARCHAR));
----
can't be cast to the destination type STRUCT(key_C VARCHAR)
# NULL values
# ---------------------------------------------------
query I
SELECT CAST(NULL AS STRUCT(a INT));
----
NULL
query I
SELECT '{a: NULL}'::STRUCT(a VARCHAR);
----
{'a': NULL}
query I
SELECT '{a:12, b:NULL}'::STRUCT(a INT, b INT);
----
{'a': 12, 'b': NULL}
query I
SELECT '{a:{c: NULL}, b: NULL, c:{d: "Ducky", e: NULL}}'::STRUCT(a STRUCT(c INT), b VARCHAR, c STRUCT(d VARCHAR, e DOUBLE));
----
{'a': {'c': NULL}, 'b': NULL, 'c': {'d': Ducky, 'e': NULL}}
# Missing values
# ---------------------------------------------------
query I
SELECT '{key_A: 2, key_C: 8}'::STRUCT(key_A INT, key_B INT, key_C FLOAT);
----
{'key_A': 2, 'key_B': NULL, 'key_C': 8.0}
query I
SELECT '{key_C: 8, key_A: 2}'::STRUCT(key_A INT, key_B DOUBLE, key_C FLOAT);
----
{'key_A': 2, 'key_B': NULL, 'key_C': 8.0}
query I
SELECT '{key_C: Quack}'::STRUCT(key_A INT, key_B VARCHAR, key_C VARCHAR);
----
{'key_A': NULL, 'key_B': NULL, 'key_C': Quack}
query I
SELECT {'key_C': 2, 'key_A': 4}::VARCHAR::STRUCT(key_A INT, key_B VARCHAR, key_C VARCHAR);
----
{'key_A': 4, 'key_B': NULL, 'key_C': 2}
query I
SELECT '{key_A:0}'::STRUCT(key_A INT, key_B VARCHAR);
----
{'key_A': 0, 'key_B': NULL}
query I
SELECT '{key_C: {key_B: 3, key_E: 🦆}, key_A: 2}'::STRUCT(key_A INT, key_C STRUCT(key_B INT, key_D INT, key_E VARCHAR));
----
{'key_A': 2, 'key_C': {'key_B': 3, 'key_D': NULL, 'key_E': 🦆}}
query I
SELECT '{a:{b:{b:300}, c:12}, c:{a:"DuckParty"}}'::STRUCT(a STRUCT(b STRUCT(a INT, b VARCHAR), c INT), b INT, c STRUCT(a VARCHAR, b STRUCT(a INT)));
----
{'a': {'b': {'a': NULL, 'b': 300}, 'c': 12}, 'b': NULL, 'c': {'a': DuckParty, 'b': NULL}}
query I
SELECT '{}'::STRUCT(a INT, b VARCHAR);
----
{'a': NULL, 'b': NULL}
# Try Cast
# ---------------------------------------------------
query I
SELECT TRY_CAST('{key_B: "hello", key_Z: 2, key_A: 46}' AS STRUCT(key_A INT, key_B VARCHAR));
----
NULL
query I
SELECT TRY_CAST('{key_B: "hello", key_Z: 2, key_A: 46}' AS STRUCT(key_A INT, key_B VARCHAR, key_C INT));
----
NULL
query I
SELECT TRY_CAST('{key_B: "hello", key_A: 46}' AS STRUCT(key_A INT, key_B INT));
----
{'key_A': 46, 'key_B': NULL}
query I
SELECT TRY_CAST('{a:4, b:''Ducky'', c:''🦆''}' AS STRUCT(a INT, b DOUBLE, c VARCHAR));
----
{'a': 4, 'b': NULL, 'c': 🦆}
statement ok
CREATE TABLE try_cast_tbl(col VARCHAR);
statement ok
INSERT INTO try_cast_tbl (VALUES ('{a:{d:1}, b:100, c:"🦆"}'), ('{a:{X:1}, b:100, c:"🦆"}'), ('{a:{d:1}, b:100, X:"🦆"}'), ('{a:"oh oh", b:100, c:"🦆"}'), ('{a:{d:"oops"}, b:100, c:"🦆"}'), ('{a:{d:"oops"}, b:100, Z: "undercover", c:"🦆"}'));
query I
SELECT TRY_CAST(col AS STRUCT(a STRUCT(d INT), b DOUBLE, c VARCHAR)) FROM try_cast_tbl;
----
{'a': {'d': 1}, 'b': 100.0, 'c': 🦆}
{'a': NULL, 'b': 100.0, 'c': 🦆}
NULL
{'a': NULL, 'b': 100.0, 'c': 🦆}
{'a': {'d': NULL}, 'b': 100.0, 'c': 🦆}
NULL
# Syntax error checking
# ---------------------------------------------------
statement error
SELECT CAST('[{a:3}]' AS STRUCT(a INT));
----
can't be cast to the destination type STRUCT(a INTEGER)
statement error
SELECT CAST('Hello World' AS STRUCT(a VARCHAR));
----
can't be cast to the destination type STRUCT(a VARCHAR)
statement error
SELECT CAST('{a: 3}}' AS STRUCT(a INT));
----
can't be cast to the destination type STRUCT(a INTEGER)
statement error
SELECT CAST('{a: 3, b:{c: 8}}}' AS STRUCT(a INT, b STRUCT(c INT)));
----
can't be cast to the destination type STRUCT(a INTEGER, b STRUCT(c INTEGER))
statement error
SELECT CAST('{{a: 3}' AS STRUCT(a INT));
----
can't be cast to the destination type STRUCT(a INTEGER)
statement error
SELECT CAST('{a:3}, {b:1}' AS STRUCT(a INT, b INT));
----
can't be cast to the destination type STRUCT(a INTEGER, b INTEGER)
statement error
SELECT CAST('{a:{a:3}, b:{{b:1}}}' AS STRUCT(a STRUCT(a INT), b STRUCT(b INT)));
----
can't be cast to the destination type STRUCT(b INTEGER)
statement error
SELECT CAST('{a: 3 1}' AS STRUCT(a INT));
----
Could not convert string '3 1' to INT32
statement error
SELECT CAST('{a:3,, b:1}' AS STRUCT(a INT, b INT));
----
can't be cast to the destination type STRUCT(a INTEGER, b INTEGER)
statement error
SELECT CAST('}{a:5}' AS STRUCT(a INT));
----
can't be cast to the destination type STRUCT(a INTEGER)
statement error
SELECT CAST('{a:{b:{d: 800}, {c: "Duck"}}}' AS STRUCT(a STRUCT(b STRUCT(d INT), c STRUCT(c VARCHAR))));
----
can't be cast to the destination type STRUCT(b STRUCT(d INTEGER), c STRUCT(c VARCHAR))
statement error
SELECT CAST('{[{]}}' AS STRUCT(a VARCHAR[]));
----
can't be cast to the destination type STRUCT(a VARCHAR[])
# Test WHERE clause
# ---------------------------------------------------
statement ok
CREATE TABLE tbl(col VARCHAR);
statement ok
INSERT INTO tbl (VALUES ('{a:DUCK, b:12}'), ('{a:"DB", b:21}'), ('{a:"Quack", b:2}'));
query I
SELECT cast(col as STRUCT(a VARCHAR, b INT)).a FROM tbl WHERE cast(col as STRUCT(a VARCHAR, b INT)).b=12;
----
DUCK
# CSV reader
# ---------------------------------------------------
statement ok
CREATE TABLE assorted_structs(col1 STRUCT(a INT, b VARCHAR));
statement ok
COPY (SELECT '{a: 8, b: "hello, DuckDB"}') TO '__TEST_DIR__/assorted_structs.csv';
statement ok
COPY assorted_structs FROM '__TEST_DIR__/assorted_structs.csv';
query I
SELECT * FROM assorted_structs;
----
{'a': 8, 'b': 'hello, DuckDB'}
# JSON format to Struct testing
# ---------------------------------------------------
require json
statement ok
CREATE TABLE json_tbl(col1 VARCHAR);
statement ok
INSERT INTO json_tbl (VALUES ('{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil''s Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}'));
query I
SELECT col1::STRUCT(
id VARCHAR,
type VARCHAR,
name VARCHAR,
ppu FLOAT,
batters STRUCT(
batter STRUCT(
id VARCHAR,
type VARCHAR
)[]
),
topping STRUCT(
id VARCHAR,
type VARCHAR
)[]
) FROM json_tbl;
----
{'id': 0001, 'type': donut, 'name': Cake, 'ppu': 0.55, 'batters': {'batter': [{'id': 1001, 'type': Regular}, {'id': 1002, 'type': Chocolate}, {'id': 1003, 'type': Blueberry}, {'id': 1004, 'type': 'Devil\'s Food'}]}, 'topping': [{'id': 5001, 'type': None}, {'id': 5002, 'type': Glazed}, {'id': 5005, 'type': Sugar}, {'id': 5007, 'type': Powdered Sugar}, {'id': 5006, 'type': Chocolate with Sprinkles}, {'id': 5003, 'type': Chocolate}, {'id': 5004, 'type': Maple}]}
# ---------------------------------------------------
statement ok
CREATE TABLE json_tbl2(col1 JSON);
statement ok
INSERT INTO json_tbl2 (VALUES ('{"A": "Ducky", "B": [3, 50, 8, 43], "C":{"A": "TEST", "B": 0.9, "C": [0.0, 9, 30.2]} }' ),
('{"A": "TESTY", "B": [4], "C":{"A": "🦆", "B": 6.12, "C": [0.099, 1.6]} }' ),
('{"A": "Hello World", "B": [0, 0, 2, 500, 0, 8], "C":{"A": "DuckieDuck !", "B": 3000, "C": [0]} }' ),
('{"A": "", "B": [], "C":{"A": "", "B": 0, "C": []} }' ));
query I
SELECT col1::VARCHAR::STRUCT(A VARCHAR, B INT[], C STRUCT(A VARCHAR, B FLOAT, C DOUBLE[])) FROM json_tbl2;
----
{'A': Ducky, 'B': [3, 50, 8, 43], 'C': {'A': TEST, 'B': 0.9, 'C': [0.0, 9.0, 30.2]}}
{'A': TESTY, 'B': [4], 'C': {'A': 🦆, 'B': 6.12, 'C': [0.099, 1.6]}}
{'A': Hello World, 'B': [0, 0, 2, 500, 0, 8], 'C': {'A': DuckieDuck !, 'B': 3000.0, 'C': [0.0]}}
{'A': '', 'B': [], 'C': {'A': '', 'B': 0.0, 'C': []}}

View File

@@ -0,0 +1,263 @@
# name: test/sql/cast/string_to_struct_escapes.test
# group: [cast]
query I
SELECT $${name: value, age: 30}$$::STRUCT(name VARCHAR, age INT);
----
{'name': value, 'age': 30}
query I
SELECT $${name: John, city: "New York"}$$::STRUCT(name VARCHAR, city VARCHAR);
----
{'name': John, 'city': New York}
query I
SELECT $${quote_at_start: "\"test\"", age: 30}$$::STRUCT(quote_at_start VARCHAR, age INT);
----
{'quote_at_start': '"test"', 'age': 30}
query I
SELECT $${user_name: Alice, status: active}$$::STRUCT(user_name VARCHAR, status VARCHAR);
----
{'user_name': Alice, 'status': active}
query I
SELECT $${special_characters: "comma, backslash\\", age: 30}$$::STRUCT(special_characters VARCHAR, age INT);
----
{'special_characters': 'comma, backslash\\', 'age': 30}
query I
SELECT $${a: 10, b: "hello world"}$$::STRUCT(a INT, b VARCHAR);
----
{'a': 10, 'b': hello world}
query I
SELECT $${first_name: "John", last_name: "Doe", age: 28}$$::STRUCT(first_name VARCHAR, last_name VARCHAR, age INT);
----
{'first_name': John, 'last_name': Doe, 'age': 28}
query I
SELECT $${first name: John, age: 30}$$::STRUCT("first name" VARCHAR, age INT);
----
{'first name': John, 'age': 30}
# Invalid: Value contains a quote that isn't escaped
statement error
SELECT $${name: "John "Doe"}$$::STRUCT(name VARCHAR);
----
can't be cast to the destination type
# second key has no ending character (:)
statement error
SELECT $${name: John, age, 30}$$::STRUCT(name VARCHAR, age INT);
----
can't be cast to the destination type
# Name is free to contain `,`, only `:` is problematic
query I
SELECT $${user,name: Alice, age: 30}$$::STRUCT("user,name" VARCHAR, age INT);
----
{'user,name': Alice, 'age': 30}
# Invalid: Contains an unescaped closing bracket
statement error
SELECT $${name: Alice, age: 30})$$::STRUCT(name VARCHAR, age INT);
----
can't be cast to the destination type
# Invalid: Name contains a backslash
statement error
SELECT $${"backslash\name": value}$$::STRUCT("backslash\name" VARCHAR);
----
can't be cast to the destination type
# Valid: Name contains a backslash outside of quotes, interpreted as literal
query III
SELECT $${backslash\name: value}$$::STRUCT("backslash\name" VARCHAR) a, a::VARCHAR::STRUCT("backslash\name" VARCHAR) b, a == b;
----
{'backslash\\name': value} {'backslash\\name': value} true
# first `:` is not escaped, won't match the "name:" struct key
statement error
SELECT $${name: test, value: 30}$$::STRUCT("name:" VARCHAR, value INT);
----
can't be cast to the destination type
# Invalid: Name can contain escaped `:`, but only in quotes
statement error
SELECT $${name\:: test, value: 30}$$::STRUCT("name:" VARCHAR, value INT);
----
can't be cast to the destination type STRUCT("name:" VARCHAR, "value" INTEGER)
# Valid: Name can contain escaped `:` in quotes
query I
SELECT $${"name\:": test, value: 30}$$::STRUCT("name:" VARCHAR, value INT);
----
{'name:': test, 'value': 30}
# Name consists of `{}`, not a problem, with this syntax we expect a name, which is a plain string
# Only reserved character there is `:` (and quotes, and backslash of course)
query I
SELECT $${{name}: John, age: 3}$$::STRUCT("{name}" VARCHAR, age INT);
----
{'{name}': John, 'age': 3}
# Name has `{` which normally starts a bracket that disables interpreting escape characters
query I
SELECT $${{\"name\"}: John, age: 3}$$::STRUCT("{""name""}" VARCHAR, age INT);
----
{'{"name"}': John, 'age': 3}
# Name has `{` which normally starts a bracket that disables interpreting escape characters
query I
SELECT $${{\'name\'}: John, age: 3}$$::STRUCT("{'name'}" VARCHAR, age INT);
----
{'{\'name\'}': John, 'age': 3}
# Invalid: Unterminated string value
statement error
SELECT $${name: "John, age: 30}$$::STRUCT(name VARCHAR, age INT);
----
can't be cast to the destination type
query I
SELECT $${}$$::STRUCT(name VARCHAR, age INT);
----
{'name': NULL, 'age': NULL}
# STRUCT with whitespace around colon (escaped)
query I
SELECT $${name : John, age : 30}$$::STRUCT(name VARCHAR, age INT);
----
{'name': John, 'age': 30}
# STRUCT with escaped backslash in value
query I
SELECT $${path: "C:\\Users\\John"}$$::STRUCT(path VARCHAR);
----
{'path': 'C:\\Users\\John'}
# STRUCT with special characters in value, properly escaped
query I
SELECT $${description: "Special characters: \\, \", \', (, )"}$$::STRUCT(description VARCHAR);
----
{'description': 'Special characters: \\, ", \', (, )'}
statement error
SELECT $${first\ name: "John", age: 30}$$::STRUCT("first name" VARCHAR, age INT);
----
can't be cast to the destination type STRUCT("first name" VARCHAR, age INTEGER)
# Valid: Name with escaped space
query I
SELECT $${"first\ name": "John", age: 30}$$::STRUCT("first name" VARCHAR, age INT);
----
{'first name': John, 'age': 30}
# Valid: Name with escaped quote
query I
SELECT $${\"quote at start\": "value", age: 30}$$::STRUCT("""quote at start""" VARCHAR, age INT);
----
{'"quote at start"': value, 'age': 30}
statement error
SELECT $${backslash\\name: "John Doe", age: 30}$$::STRUCT("backslash\name" VARCHAR, age INT);
----
can't be cast to the destination type STRUCT("backslash\name" VARCHAR, age INTEGER)
# Valid: Name with escaped backslash
query I
SELECT $${"backslash\\name": "John Doe", age: 30}$$::STRUCT("backslash\name" VARCHAR, age INT);
----
{'backslash\\name': John Doe, 'age': 30}
statement error
SELECT $${user\,name: "Alice", age: 25}$$::STRUCT("user,name" VARCHAR, age INT);
----
can't be cast to the destination type STRUCT("user,name" VARCHAR, age INTEGER)
# Valid: Name with escaped comma
query I
SELECT $${"user\,name": "Alice", age: 25}$$::STRUCT("user,name" VARCHAR, age INT);
----
{'user,name': Alice, 'age': 25}
# Valid: Name with comma
query I
SELECT $${"user,name": "Alice", age: 25}$$::STRUCT("user,name" VARCHAR, age INT);
----
{'user,name': Alice, 'age': 25}
statement error
SELECT $${user\(name\): "Alice", status: "active"}$$::STRUCT("user(name)" VARCHAR, status VARCHAR);
----
can't be cast to the destination type STRUCT("user(name)" VARCHAR, status VARCHAR)
# Valid: Name with escaped parenthesis
query I
SELECT $${"user\(name\)": "Alice", status: "active"}$$::STRUCT("user(name)" VARCHAR, status VARCHAR);
----
{'user(name)': Alice, 'status': active}
# Valid: Name with unescaped parenthesis
query I
SELECT $${user(name): "Alice", status: "active"}$$::STRUCT("user(name)" VARCHAR, status VARCHAR);
----
{'user(name)': Alice, 'status': active}
# Valid: Name with escaped space at end
query I
SELECT $${"user\ name\ ": "Alice", "age ": 25}$$::STRUCT("user name " VARCHAR, "age " INT);
----
{'user name ': Alice, 'age ': 25}
statement error
SELECT $${user\ name\ : "Alice", age\ : 25}$$::STRUCT("user name " VARCHAR, "age " INT);
----
can't be cast to the destination type STRUCT("user name " VARCHAR, "age " INTEGER)
# Invalid: Name contains unescaped quote
statement error
SELECT $${"quote"start": "value", age: 30}$$::STRUCT("quote""start" VARCHAR, age INT);
----
can't be cast to the destination type
# Valid: Name contains unescaped backslash outside of quotes
query I
SELECT $${backslash\name: "John", age: 30}$$::STRUCT("backslash\name" VARCHAR, age INT);
----
{'backslash\\name': John, 'age': 30}
# Valid: Name contains (unescaped) opening parenthesis
query I
SELECT $${user(name: "Alice", age: 25}$$::STRUCT("user(name" VARCHAR, age INT);
----
{'user(name': Alice, 'age': 25}
# Name is single double quote
query I
SELECT $${\": "value", age: 30}$$::STRUCT("""" VARCHAR, age INTEGER)
----
{'"': value, 'age': 30}
statement error
SELECT $${\\: "escaped", age: 30}$$::STRUCT("\" VARCHAR, age INT);
----
can't be cast to the destination type STRUCT("\" VARCHAR, age INTEGER)
# Name with only a special character (escaped)
query I
SELECT $${"\\": "escaped", age: 30}$$::STRUCT("\" VARCHAR, age INT);
----
{'\\': escaped, 'age': 30}
# Name with only a special character (not escaped)
query I
SELECT $${@: "value", age: 30}$$::STRUCT("@" VARCHAR, age INT);
----
{'@': value, 'age': 30}
query III
select $$[{'a': test}, {'a': NULL}, {'a': 'null'}, {'a': 'nUlL'}, {'a': NULL}, {'a': NULLz}, {'a': 'NULL'}]$$::STRUCT(a VARCHAR)[] a, a::VARCHAR::STRUCT(a VARCHAR)[] b, a == b
----
[{'a': test}, {'a': NULL}, {'a': 'null'}, {'a': 'nUlL'}, {'a': NULL}, {'a': NULLz}, {'a': 'NULL'}] [{'a': test}, {'a': NULL}, {'a': 'null'}, {'a': 'nUlL'}, {'a': NULL}, {'a': NULLz}, {'a': 'NULL'}] true

View File

@@ -0,0 +1,65 @@
# name: test/sql/cast/string_to_struct_roundtrip.test
# group: [cast]
query I
select $${
a:{
b:{
b:300
},
c:12
},
c:{
a:"\{DuckParty\}"
}
}$$::STRUCT(
a STRUCT(
b STRUCT(
a INT,
b VARCHAR
),
c INT
),
b INT,
c STRUCT(
a VARCHAR,
b STRUCT(
a INT
)
)
)
----
{'a': {'b': {'a': NULL, 'b': 300}, 'c': 12}, 'b': NULL, 'c': {'a': '{DuckParty}', 'b': NULL}}
# Leading and trailing spaces in struct name
query III
select $${" test ": 42}$$::STRUCT(" test " INTEGER) a, a::VARCHAR::STRUCT(" test " INTEGER) b, a == b
----
{' test ': 42} {' test ': 42} true
# Escaped quotes in struct name (double quote)
query III
select $${" \"test\" ": 42}$$::STRUCT(" ""test"" " INTEGER) a, a::VARCHAR::STRUCT(" ""test"" " INTEGER) b, a == b
----
{' "test" ': 42} {' "test" ': 42} true
# Escaped quotes in struct name (single quote)
query III
select $${" \'test\' ": 42}$$::STRUCT(" 'test' " INTEGER) a, a::VARCHAR::STRUCT(" 'test' " INTEGER) b, a == b
----
{' \'test\' ': 42} {' \'test\' ': 42} true
# Start and end name with escaped backslashes
query III
select $${"\\ test \\": 42}$$::STRUCT("\ test \" INTEGER) a, a::VARCHAR::STRUCT("\ test \" INTEGER) b, a == b
----
{'\\ test \\': 42} {'\\ test \\': 42} true
# Start and end value with escaped backslashes
query III
select $${"test": \\ test \\}$$::STRUCT("test" VARCHAR) a, a::VARCHAR::STRUCT("test" VARCHAR) b, a == b
----
{'test': \\ test \\} {'test': \\ test \\} true

View File

@@ -0,0 +1,100 @@
# name: test/sql/cast/string_to_unnamed_struct.test
# group: [cast]
# Basic single value struct
query I
select [row('a'), $$(abc)$$]
----
[(a), (abc)]
# Multiple values
query I
select [row('a', 'b', 'c'), $$(abc, def, ghi)$$]
----
[(a, b, c), (abc, def, ghi)]
# Empty unnamed struct
query I
select [row('a'),$$()$$]
----
[(a), (NULL)]
# Empty string in unnamed struct
query I
select [row('a'),$$('')$$]
----
[(a), ('')]
# Nested regular struct inside unnamed struct
query I
select [row({'amount': 21}), $$({'amount': 42})$$]
----
[({'amount': 21}), ({'amount': 42})]
# Nested unnamed struct inside unnamed struct
query I
select [row(row(21)), $$((42))$$]
----
[((21)), ((42))]
# Nested unnamed struct AND regular struct inside unnamed struct
query I
select [row(row(21), {'amount': 42}), $$((42), {amount: 21})$$]
----
[((21), {'amount': 42}), ((42), {'amount': 21})]
# List inside unnamed struct
query I
select [row([7,8,9], [10,11,12]), $$([1,2,3], [4,5,6])$$]
----
[([7, 8, 9], [10, 11, 12]), ([1, 2, 3], [4, 5, 6])]
statement error
select [row([4,5,6]), $$([1,2,3],)$$]
----
can't be cast to the destination type STRUCT(INTEGER[])
# Empty string in the second child of the unnamed struct
query I
select [row([4,5,6], 'abc'), $$([1,2,3],)$$]
----
[([4, 5, 6], abc), ([1, 2, 3], '')]
# Empty string in the second child of a named struct
query I
select [{'a': [4,5,6], 'b': 'abc'}, $${'a': [1,2,3],'b':}$$]
----
[{'a': [4, 5, 6], 'b': abc}, {'a': [1, 2, 3], 'b': ''}]
query I
select [
[
row(
row(
' test '
)
),
{'a': {
'inner':
'\ test \'
}
}
],
$$[((" test ")), {'a': (\\ test \\)}]$$
]
----
[[{'a': {'inner': ' test '}}, {'a': {'inner': \ test \}}], [{'a': {'inner': ' test '}}, {'a': {'inner': \\ test \\}}]]
query III
select [
row('test'),
$$(NULL)$$,
$$('null')$$,
$$('nUlL')$$,
$$(NuLl)$$,
$$("NULLz")$$,
$$("NULL")$$
] a, a::VARCHAR::STRUCT(a VARCHAR)[] b, a == b
----
[(test), (NULL), ('null'), ('nUlL'), (NULL), (NULLz), ('NULL')] [{'a': test}, {'a': NULL}, {'a': 'null'}, {'a': 'nUlL'}, {'a': NULL}, {'a': NULLz}, {'a': 'NULL'}] true

View File

@@ -0,0 +1,354 @@
# name: test/sql/cast/struct_to_map.test
# group: [cast]
# enable query verification
statement ok
PRAGMA enable_verification
# Basic functionality tests
# Simple cast - VARCHAR keys to VARCHAR values
query I
SELECT {"name": 'Alice', "city": 'NYC'}::MAP(VARCHAR, VARCHAR);
----
{name=Alice, city=NYC}
# Simple cast - VARCHAR keys to INT values
query I
SELECT {"age": 25, "score": 100}::MAP(VARCHAR, INT);
----
{age=25, score=100}
# Multiple rows with same field structure
query I
SELECT col::MAP(VARCHAR, INT)
FROM VALUES ({"duck": 1}),({"duck": 2}),({"duck": 3}),({"duck": 4}),({"duck": 5})
AS tab(col);
----
{duck=1}
{duck=2}
{duck=3}
{duck=4}
{duck=5}
# Multiple fields in a single struct
query I
SELECT {"name": 'Alice', "age": 25, "score": 95}::MAP(VARCHAR, VARCHAR);
----
{name=Alice, age=25, score=95}
# Key type casting tests
# Cast VARCHAR keys to INT keys (keeps null values)
query I
SELECT col::MAP(INT, INT)
FROM VALUES ({"1": 1}),({"2": 2}),({"3": 3}),({"4": 4}),({"5": 5})
AS tab(col);
----
{1=1, 2=NULL, 3=NULL, 4=NULL, 5=NULL}
{1=NULL, 2=2, 3=NULL, 4=NULL, 5=NULL}
{1=NULL, 2=NULL, 3=3, 4=NULL, 5=NULL}
{1=NULL, 2=NULL, 3=NULL, 4=4, 5=NULL}
{1=NULL, 2=NULL, 3=NULL, 4=NULL, 5=5}
# Cast VARCHAR keys to BIGINT keys
query I
SELECT {"123456789": 42}::MAP(BIGINT, INT);
----
{123456789=42}
# Cast VARCHAR keys to DOUBLE keys
query I
SELECT {"3.14": 100}::MAP(DOUBLE, INT);
----
{3.14=100}
# Value type casting tests
# Cast INT values to VARCHAR
query I
SELECT {"age": 25, "score": 100}::MAP(VARCHAR, VARCHAR);
----
{age=25, score=100}
# Cast different numeric types to BIGINT
query I
SELECT {"small": 1, "big": 999999999}::MAP(VARCHAR, BIGINT);
----
{small=1, big=999999999}
# Cast to DOUBLE values
query I
SELECT {"pi": 3, "e": 2}::MAP(VARCHAR, DOUBLE);
----
{pi=3.0, e=2.0}
# Mixed type casting - both keys and values
query I
SELECT {"1": 100, "2": 200}::MAP(INT, BIGINT);
----
{1=100, 2=200}
# NULL handling tests
# NULL struct becomes NULL map
query I
SELECT (NULL::STRUCT(name VARCHAR, age INT))::MAP(VARCHAR, VARCHAR);
----
NULL
# NULL field values are preserved
query I
SELECT {"name": 'Alice', "age": NULL}::MAP(VARCHAR, VARCHAR);
----
{name=Alice, age=NULL}
# Multiple NULL values
query I
SELECT {"a": NULL, "b": NULL, "c": 'value'}::MAP(VARCHAR, VARCHAR);
----
{a=NULL, b=NULL, c=value}
# Constant vector tests
# Single constant struct
query I
SELECT x::MAP(VARCHAR, INT) FROM (SELECT {"constant": 42} as x FROM range(5));
----
{constant=42}
{constant=42}
{constant=42}
{constant=42}
{constant=42}
# Complex nested type tests
# STRUCT values to STRUCT values
query I
SELECT {"person": {"name": 'Alice', "age": 25}}::MAP(VARCHAR, STRUCT(name VARCHAR, age INT));
----
{person={'name': Alice, 'age': 25}}
# LIST values to LIST values
query I
SELECT {"numbers": [1,2,3], "letters": ['a','b']}::MAP(VARCHAR, VARCHAR[]);
----
{numbers=[1, 2, 3], letters=[a, b]}
# Nested MAP values
query I
SELECT {meta: MAP{'key': 'value'}}::MAP(VARCHAR, MAP(VARCHAR, VARCHAR));
----
{meta={key=value}}
# Complex nested structure
query I
SELECT col::MAP(VARCHAR, MAP(VARCHAR, INT))
FROM VALUES ({ data: MAP{'count': 10, 'total': 100} })
AS tab(col);
----
{data={count=10, total=100}}
# Edge cases
# Constant vector select
query I
SELECT {"value": 42}::MAP(VARCHAR, INT)
FROM range(1, 1001)
LIMIT 5;
----
{value=42}
{value=42}
{value=42}
{value=42}
{value=42}
# Make sure nothing breaks if we change the vector type
statement ok
pragma debug_verify_vector='dictionary_expression'
query I
SELECT TRY_CAST(col AS MAP(VARCHAR, integer))
FROM (
SELECT CASE WHEN (i % 5 == 0) THEN NULL else {'a': i::varchar} END as col
FROM range(1, 1001) t(i)
)
LIMIT 5;
----
{a=1}
{a=2}
{a=3}
{a=4}
NULL
statement ok
pragma debug_verify_vector='none'
# Single field struct
query I
SELECT {"single": 'value'}::MAP(VARCHAR, VARCHAR);
----
{single=value}
# Large number of fields
query I
SELECT {
"f1": 1, "f2": 2, "f3": 3, "f4": 4, "f5": 5,
"f6": 6, "f7": 7, "f8": 8, "f9": 9, "f10": 10
}::MAP(VARCHAR, INT);
----
{f1=1, f2=2, f3=3, f4=4, f5=5, f6=6, f7=7, f8=8, f9=9, f10=10}
# Error cases
# Cannot cast unnamed struct to MAP
statement error
SELECT (1, 2, 3)::MAP(INT, INT);
----
Cannot cast unnamed STRUCTs to MAP
# Key casting can fail
statement error
SELECT col::MAP(INT, INT)
FROM VALUES ({"duck": 1}),({"goose": 2})
AS tab(col);
----
Conversion Error: Could not convert string 'duck' to INT32
# Value casting can fail
statement error
SELECT {"number": 'not_a_number'}::MAP(VARCHAR, INT);
----
Conversion Error: Could not convert string 'not_a_number' to INT32
# Special character handling in keys
# Keys with spaces
query I
SELECT {"first name": 'Alice', "last name": 'Smith'}::MAP(VARCHAR, VARCHAR);
----
{first name=Alice, last name=Smith}
# Keys with special characters
query I
SELECT {"key-with-dashes": 1, "key_with_underscores": 2, "key.with.dots": 3}::MAP(VARCHAR, INT);
----
{key-with-dashes=1, key_with_underscores=2, key.with.dots=3}
# Unicode keys
query I
SELECT {"测试": 'test', "🦆": 'duck'}::MAP(VARCHAR, VARCHAR);
----
{=test, 🦆=duck}
# Case sensitivity preservation
query I
SELECT {"CamelCase": 1, "lowercase": 2, "UPPERCASE": 3}::MAP(VARCHAR, INT);
----
{CamelCase=1, lowercase=2, UPPERCASE=3}
# Performance and batching tests
# Large batch of rows
query I
SELECT col::MAP(VARCHAR, INT)
FROM (
SELECT {"value": i} as col
FROM range(1, 1001) t(i)
)
LIMIT 5;
----
{value=1}
{value=2}
{value=3}
{value=4}
{value=5}
# Mixed field counts across rows
query I
SELECT col::MAP(VARCHAR, VARCHAR)
FROM VALUES
({"a": '1'}),
({"A": '1', "b": '2'}),
({"a": '1', "B": '2', "c": '3'}),
({"x": 'single'}),
({"many": '1', "fields": '2', "here": '3', "total": '4', "five": '5'})
AS tab(col);
----
{a=1, b=NULL, c=NULL, x=NULL, many=NULL, fields=NULL, here=NULL, total=NULL, five=NULL}
{a=1, b=2, c=NULL, x=NULL, many=NULL, fields=NULL, here=NULL, total=NULL, five=NULL}
{a=1, b=2, c=3, x=NULL, many=NULL, fields=NULL, here=NULL, total=NULL, five=NULL}
{a=NULL, b=NULL, c=NULL, x=single, many=NULL, fields=NULL, here=NULL, total=NULL, five=NULL}
{a=NULL, b=NULL, c=NULL, x=NULL, many=1, fields=2, here=3, total=4, five=5}
# Type compatibility tests
# All numeric types as values
query I
SELECT {
"tinyint": 1::TINYINT,
"smallint": 2::SMALLINT,
"int": 3::INT,
"bigint": 4::BIGINT
}::MAP(VARCHAR, BIGINT);
----
{tinyint=1, smallint=2, int=3, bigint=4}
# String types as values
query I
SELECT {
"varchar": 'hello'::VARCHAR,
"text": 'world'::TEXT
}::MAP(VARCHAR, VARCHAR);
----
{varchar=hello, text=world}
# Date/time types as values
query I
SELECT {
"date": '2023-01-01'::DATE,
"time": '12:00:00'::TIME
}::MAP(VARCHAR, VARCHAR);
----
{date=2023-01-01, time='12:00:00'}
# Boolean values
query I
SELECT {"true_val": true, "false_val": false}::MAP(VARCHAR, VARCHAR);
----
{true_val=true, false_val=false}
# Decimal values
query I
SELECT {"price": 19.99::DECIMAL(10,2)}::MAP(VARCHAR, VARCHAR);
----
{price=19.99}
# Interoperability tests
# Use in WHERE clause
query I
SELECT *
FROM VALUES ({"status": 'active'}), ({"status": 'inactive'})
AS tab(col)
WHERE (col::MAP(VARCHAR, VARCHAR))['status'] = 'active';
----
{'status': active}
# Use in aggregations
query I
SELECT COUNT(*)
FROM VALUES ({"type": 'A'}), ({"type": 'B'}), ({"type": 'A'})
AS tab(col)
WHERE (col::MAP(VARCHAR, VARCHAR))['type'] = 'A';
----
2
# Complex nested example from original test
query I
SELECT col::MAP(VARCHAR, MAP(VARCHAR, INT))
FROM VALUES ({ nested: MAP { 'inner_key': 707 } })
AS tab(col);
----
{nested={inner_key=707}}

View File

@@ -0,0 +1,427 @@
# name: test/sql/cast/test_bit_cast.test
# description: Test casting from and to BitString
# group: [cast]
statement ok
PRAGMA enable_verification
statement ok
CREATE TABLE bits (b bit);
statement ok
INSERT INTO bits VALUES('00001111');
# cast to bool
# ---------------------------------------------------
statement error
SELECT bitstring('1', 9)::BOOL;
----
Conversion Error: Bitstring doesn't fit inside of UINT8
query I
SELECT b::BOOLEAN FROM bits;
----
true
query I
SELECT '1'::BIT::BOOL;
----
true
query I
SELECT '0'::BIT::BOOL;
----
false
# casting to numerical types
# ---------------------------------------------------
query I
SELECT b::TINYINT FROM bits;
----
15
query I
SELECT b::SMALLINT FROM bits;
----
15
query I
SELECT b::INTEGER FROM bits;
----
15
query I
SELECT b::BIGINT FROM bits;
----
15
query I
SELECT b::UTINYINT FROM bits;
----
15
query I
SELECT b::USMALLINT FROM bits;
----
15
query I
SELECT b::UINTEGER FROM bits;
----
15
query I
SELECT b::UBIGINT FROM bits;
----
15
query I
SELECT b::HUGEINT FROM bits;
----
15
query I
SELECT b::UHUGEINT FROM bits;
----
15
query I
SELECT b::FLOAT FROM bits;
----
2.1e-44
query I
SELECT b::DOUBLE FROM bits;
----
7.4e-323
query I
SELECT '100001111000011110000111100001111'::BIT::BIGINT;
----
4547612431
# numeric to bitstring
# ---------------------------------------------------
query I
SELECT 15::BOOLEAN::BIT;
----
00000001
query I
SELECT 15::TINYINT::BIT;
----
00001111
query I
SELECT 15::SMALLINT::BIT;
----
0000000000001111
query I
SELECT 15::BIT;
----
00000000000000000000000000001111
query I
SELECT 15::BIGINT::BIT;
----
0000000000000000000000000000000000000000000000000000000000001111
query I
SELECT 15::HUGEINT::BIT;
----
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111
query I
SELECT 15::UHUGEINT::BIT;
----
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111
query I
SELECT 2.1e-44::FLOAT::BIT;
----
00000000000000000000000000001111
query I
SELECT 7.4e-323::BIT;
----
0000000000000000000000000000000000000000000000000000000000001111
# bitstrings that are too large for casted-to type
# ---------------------------------------------------
statement error
SELECT bitstring('1', 9)::TINYINT;
----
Conversion Error: Bitstring doesn't fit inside of INT8
statement error
SELECT bitstring('1', 17)::SMALLINT;
----
Conversion Error: Bitstring doesn't fit inside of INT16
statement error
SELECT bitstring('1', 33)::INT;
----
Conversion Error: Bitstring doesn't fit inside of INT32
statement error
SELECT bitstring('1', 65)::BIGINT;
----
Conversion Error: Bitstring doesn't fit inside of INT64
statement error
SELECT bitstring('1', 33)::FLOAT;
----
Conversion Error: Bitstring doesn't fit inside of FLOAT
statement error
SELECT bitstring('1', 65)::DOUBLE;
----
Conversion Error: Bitstring doesn't fit inside of DOUBLE
# casting to BLOB type
# ---------------------------------------------------
query I
SELECT b::BLOB FROM bits;
----
\x0F
query I
SELECT bitstring('1111', 32)::BLOB;
----
\x00\x00\x00\x0F
query I
SELECT '1111'::BIT::BLOB;
----
\x0F
query I
select 'ab'::BLOB::BIT::BLOB;
----
ab
query I
select 'a'::BLOB::BIT::BLOB;
----
a
query I
SELECT bitstring('1111', 33)::BLOB;
----
\x00\x00\x00\x00\x0F
# casting from BLOB type
# ---------------------------------------------------
query I
SELECT 'AAAA'::BLOB::BIT;
----
01000001010000010100000101000001
statement error
SELECT ''::BLOB::BIT;
----
Conversion Error: Cannot cast empty BLOB to BIT
# negative numbers
# ---------------------------------------------------
query I
SELECT (-15)::TINYINT::BIT;
----
11110001
query I
SELECT (-15)::HUGEINT::BIT;
----
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110001
# signed integer limits -> Bit
# ---------------------------------------------------
query I
SELECT (127)::TINYINT::BIT;
----
01111111
query I
SELECT (-128)::TINYINT::BIT;
----
10000000
query I
SELECT (32767)::SMALLINT::BIT;
----
0111111111111111
query I
SELECT (-32768)::SMALLINT::BIT;
----
1000000000000000
query I
SELECT (2147483647)::INT::BIT;
----
01111111111111111111111111111111
query I
SELECT (-2147483648)::INT::BIT;
----
10000000000000000000000000000000
query I
SELECT (9223372036854775807)::BIGINT::BIT;
----
0111111111111111111111111111111111111111111111111111111111111111
query I
SELECT (-9223372036854775808)::BIGINT::BIT;
----
1000000000000000000000000000000000000000000000000000000000000000
query I
SELECT (170141183460469231731687303715884105727)::HUGEINT::BIT;
----
01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
query I
SELECT (-170141183460469231731687303715884105728)::HUGEINT::BIT;
----
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
# Bit -> signed integer limits
# ---------------------------------------------------
query I
SELECT '01111111'::BIT::TINYINT;
----
127
query I
SELECT '10000000'::BIT::TINYINT;
----
-128
query I
SELECT '0111111111111111'::BIT::SMALLINT;
----
32767
query I
SELECT '1000000000000000'::BIT::SMALLINT;
----
-32768
query I
SELECT '01111111111111111111111111111111'::BIT::INT;
----
2147483647
query I
SELECT '10000000000000000000000000000000'::BIT::INT;
----
-2147483648
query I
SELECT '0111111111111111111111111111111111111111111111111111111111111111'::BIT::BIGINT;
----
9223372036854775807
query I
SELECT '1000000000000000000000000000000000000000000000000000000000000000'::BIT::BIGINT;
----
-9223372036854775808
query I
SELECT '01111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'::BIT::HUGEINT;
----
170141183460469231731687303715884105727
query I
SELECT '10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'::BIT::HUGEINT;
----
-170141183460469231731687303715884105728
# unsigned integer limits -> Bit
# ---------------------------------------------------
query I
SELECT (255)::UTINYINT::BIT;
----
11111111
query I
SELECT (65535)::USMALLINT::BIT;
----
1111111111111111
query I
SELECT (4294967295)::UINTEGER::BIT;
----
11111111111111111111111111111111
query I
SELECT (18446744073709551615)::UBIGINT::BIT;
----
1111111111111111111111111111111111111111111111111111111111111111
query I
SELECT '340282366920938463463374607431768211455'::UHUGEINT::BIT;
----
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
# Bit -> unsigned integer limits
# ---------------------------------------------------
query I
SELECT '11111111'::BIT::UTINYINT;
----
255
query I
SELECT '1111111111111111'::BIT::USMALLINT;
----
65535
query I
SELECT '11111111111111111111111111111111'::BIT::UINTEGER;
----
4294967295
query I
SELECT '1111111111111111111111111111111111111111111111111111111111111111'::BIT::UBIGINT;
----
18446744073709551615
# float limits -> Bit
# ---------------------------------------------------
query I
SELECT (3.4028235e+38)::FLOAT::BIT;
----
01111111011111111111111111111111
query I
SELECT (1.7976931348623157e+308)::DOUBLE::BIT;
----
0111111111101111111111111111111111111111111111111111111111111111
# Bit -> float limits
# ---------------------------------------------------
query I
SELECT '01111111011111111111111111111111'::BIT::FLOAT;
----
3.4028235e+38
query I
SELECT '0111111111101111111111111111111111111111111111111111111111111111'::BIT::DOUBLE;
----
1.7976931348623157e+308
# NULL <-> Bit
# ---------------------------------------------------
query I
SELECT NULL::BIT;
----
NULL
query I
SELECT NULL::BIT::INT;
----
NULL

View File

@@ -0,0 +1,230 @@
# name: test/sql/cast/test_boolean_cast.test
# description: Test boolean casts
# group: [cast]
statement ok
PRAGMA enable_verification
query T
SELECT CAST(1=1 AS VARCHAR)
----
true
query T
SELECT CAST(1=0 AS VARCHAR)
----
false
query T
SELECT CAST(12345 AS BOOLEAN)
----
true
query T
SELECT CAST('true' AS BOOLEAN)
----
1
query T
SELECT CAST('t' AS BOOLEAN)
----
1
query T
SELECT CAST('TRUE' AS BOOLEAN)
----
1
query T
SELECT CAST('yes' AS BOOLEAN)
----
1
query T
SELECT CAST('YeS' AS BOOLEAN)
----
1
query T
SELECT CAST('y' AS BOOLEAN)
----
1
query T
SELECT CAST('false' AS BOOLEAN)
----
0
query T
SELECT CAST('f' AS BOOLEAN)
----
0
query T
SELECT CAST('FALSE' AS BOOLEAN)
----
0
query T
SELECT CAST('no' AS BOOLEAN)
----
0
query T
SELECT CAST('nO' AS BOOLEAN)
----
0
query T
SELECT CAST('n' AS BOOLEAN)
----
0
statement error
SELECT CAST('12345' AS BOOLEAN)
----
statement ok
CREATE TABLE tbl AS SELECT 0 AS yes
query T
SELECT CAST(yes AS BOOLEAN) FROM tbl
----
0
statement error
SELECT CAST(yes AS BOOLEAN)
----
Binder Error: Referenced column "yes" not found in FROM clause!
query T
SELECT CAST(CAST('12345' AS INTEGER) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS INTEGER) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS tinyint) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS tinyint) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS smallint) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS smallint) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS integer) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS integer) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS bigint) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS bigint) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS decimal) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS decimal) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS decimal(1,0)) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS decimal(1,0)) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS decimal(9,0)) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS decimal(9,0)) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS decimal(38,0)) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS decimal(38,0)) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS float) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS float) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS double) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS double) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS HUGEINT) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS HUGEINT) AS BOOLEAN)
----
0
query T
SELECT CAST(CAST('1' AS UHUGEINT) AS BOOLEAN)
----
1
query T
SELECT CAST(CAST('0' AS UHUGEINT) AS BOOLEAN)
----
0

View File

@@ -0,0 +1,50 @@
# name: test/sql/cast/test_exponent_in_cast.test
# description: Test exponents in cast
# group: [cast]
statement ok
PRAGMA enable_verification
statement error
SELECT CAST('e1' AS INTEGER);
----
statement error
SELECT CAST(' e1' AS INTEGER);
----
statement error
SELECT CAST(' E1' AS INTEGER);
----
statement error
SELECT CAST('e1' AS DOUBLE);
----
statement error
SELECT CAST(' e1' AS DOUBLE);
----
statement error
SELECT CAST(' E1' AS DOUBLE);
----
query I
SELECT CAST('1e1' AS INTEGER);
----
10
query I
SELECT CAST(' 1e1' AS INTEGER);
----
10
query I
SELECT CAST('1e1' AS DOUBLE);
----
10.0
query I
SELECT CAST(' 1e1' AS DOUBLE);
----
10.0

View File

@@ -0,0 +1,154 @@
# name: test/sql/cast/test_string_binary_cast.test
# group: [cast]
foreach prefix 0b 0B
# Empty binary should fail
statement error
SELECT '${prefix}'::INT
----
# Binary with invalid characters should fail
statement error
SELECT '${prefix}2'::INT
----
statement error
SELECT '${prefix}10105'::INT
----
# Negative binary should fail
statement error
SELECT '${prefix}-1'::INT
----
statement error
SELECT '-${prefix}1'::INT
----
# Basic asserts
query I
SELECT '${prefix}1'::INT
----
1
query I
SELECT '${prefix}10'::INT
----
2
query I
SELECT '${prefix}11'::INT
----
3
query I
SELECT '${prefix}0000000'::INT
----
0
# Allow underscores as digit separators
query I
SELECT '${prefix}1_0'::INT
----
2
query I
SELECT '${prefix}1_0_0'::INT
----
4
query I
SELECT '${prefix}11110000_11110000'::INT
----
61680
# But dont allow them at the start or end
statement error
SELECT '${prefix}_1'::INT
----
statement error
SELECT '${prefix}1_'::INT
----
statement error
SELECT '${prefix}1_0_'::INT
----
statement error
SELECT '${prefix}_1_0'::INT
----
# Property check!
foreach binary 1 01 00 0_0 10 10101 1001 0001 1111 1111_1111 01111111111111111111111111111111 01111111_11111111_11111111_11111111
query I
WITH binary_string as (select replace('${binary}', '_', '') as str)
SELECT
list_sum([ (CASE WHEN str[i+1] = '0' THEN 0 ELSE 1 END) * (2 ** (len(str)-(i+1))) for i in range(len(str))])::INT
==
'${prefix}${binary}'::INT
FROM binary_string
----
true
endloop
# Test limits
query I
SELECT '${prefix}0000000000000000000000000000000001111111'::TINYINT
----
127
query I
SELECT '${prefix}0000000000000000000000000000000011111111'::UINT8
----
255
statement error
SELECT '${prefix}00000000000000000000000000000000111111111'::TINYINT
----
query I
SELECT '${prefix}1111111111111111111111111111111'::INT
----
2147483647
statement error
SELECT '${prefix}11111111111111111111111111111111'::INT
----
query I
SELECT '${prefix}01111111111111111111111111111111'::UINT32
----
2147483647
query I
SELECT '${prefix}11111111111111111111111111111111'::UINT32
----
4294967295
query I
SELECT '${prefix}11111111111111111111111111111111'::BIGINT
----
4294967295
query I
SELECT '${prefix}111111111111111111111111111111111111111111111111111111111111111'::BIGINT
----
9223372036854775807
statement error
SELECT '${prefix}1111111111111111111111111111111111111111111111111111111111111111'::BIGINT
----
query I
SELECT '${prefix}1111111111111111111111111111111111111111111111111111111111111111'::UINT64
----
18446744073709551615
endloop

View File

@@ -0,0 +1,260 @@
# name: test/sql/cast/test_string_cast.test
# description: Test string casts
# group: [cast]
statement ok
PRAGMA enable_verification
query TTT
SELECT (1=1)::VARCHAR, (1=0)::VARCHAR, NULL::BOOLEAN::VARCHAR
----
true
false
NULL
query TTT
SELECT 1::TINYINT::VARCHAR, 12::TINYINT::VARCHAR, (-125)::TINYINT::VARCHAR
----
1
12
-125
query TTT
SELECT 1::SMALLINT::VARCHAR, 12442::SMALLINT::VARCHAR, (-32153)::SMALLINT::VARCHAR
----
1
12442
-32153
query TTT
SELECT 1::INTEGER::VARCHAR, 12442952::INTEGER::VARCHAR, (-2000000111)::INTEGER::VARCHAR
----
1
12442952
-2000000111
query TTT
SELECT 1::BIGINT::VARCHAR, 1244295295289253::BIGINT::VARCHAR, (-2000000111551166)::BIGINT::VARCHAR
----
1
1244295295289253
-2000000111551166
query TTT
SELECT 2::FLOAT::VARCHAR, 0.5::FLOAT::VARCHAR, (-128.5)::FLOAT::VARCHAR
----
2.0
0.5
-128.5
query TTT
SELECT 2::DOUBLE::VARCHAR, 0.5::DOUBLE::VARCHAR, (-128.5)::DOUBLE::VARCHAR
----
2.0
0.5
-128.5
query IIIII
SELECT '0xF'::INTEGER, '0x0'::INTEGER, '0xFEE'::INTEGER, '0xfee'::INTEGER, '0x00FEE'::INTEGER
----
15
0
4078
4078
4078
# Empty hex fails
statement error
SELECT '0x'::INT
----
statement error
SELECT '0X'::INT
----
# Hex with invalid characters fails
statement error
SELECT '0xHELLO'::INT
----
# Overflow with very large numbers
statement error
SELECT '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'::INT
----
# Allowed upper bounds for casting from hex strings to signed integers
query IIII
SELECT '0x7F'::TINYINT, '0x7FFF'::SMALLINT, '0x7FFFFFFF'::INT, '0x7FFFFFFFFFFFFFFF'::BIGINT
----
127
32767
2147483647
9223372036854775807
# Allowed upper bounds for casting from hex strings to unsigned integers
query IIII
SELECT '0xFF'::UINT8, '0xFFFF'::UINT16, '0xFFFFFFFF'::UINT32, '0xFFFFFFFFFFFFFFFF'::UINT64
----
255
65535
4294967295
18446744073709551615
# Lots of zeros is safe
query I
SELECT '0x000000000000000000000000000000000000000000000000000000000000000000'::INT
----
0
# Bounds exceeded for casting from hex strings to integers
statement error
SELECT '0x80'::TINYINT
----
statement error
SELECT '0x8000'::SMALLINT
----
statement error
SELECT '0x80000000'::INT
----
statement error
SELECT '0x8000000000000000'::BIGINT
----
statement error
SELECT '0x100'::UINT8
----
statement error
SELECT '0x10000'::UINT16
----
statement error
SELECT '0x100000000'::UINT32
----
statement error
SELECT '0x10000000000000000'::UINT64
----
# Bounds exceeded for casting from hex strings to integers, TRY_CAST should be safe
query I
SELECT TRY_CAST('0x80' AS TINYINT)
----
NULL
query I
SELECT TRY_CAST('0x8000' AS SMALLINT)
----
NULL
query I
SELECT TRY_CAST('0x80000000' AS INT)
----
NULL
query I
SELECT TRY_CAST('0x8000000000000000' AS BIGINT)
----
NULL
query I
SELECT TRY_CAST('0x100' AS UINT8)
----
NULL
query I
SELECT TRY_CAST('0x10000' AS UINT16)
----
NULL
query I
SELECT TRY_CAST('0x100000000' AS UINT32)
----
NULL
query I
SELECT TRY_CAST('0x10000000000000000' AS UINT64)
----
NULL
# Casting decimal strings to integral types should round to be consistent.
foreach inttype TINYINT SMALLINT INTEGER BIGINT HUGEINT
query I
SELECT '0.5'::${inttype};
----
1
query I
SELECT '-0.5'::${inttype};
----
-1
endloop
# Casting hex strings to integral types should round to be consistent.
foreach inttype TINYINT SMALLINT INTEGER BIGINT
query I
SELECT '0x1e'::${inttype};
----
30
endloop
# Varied case casting should be consistent
foreach hex 0xfade 0Xfade 0xFADE 0XFADE 0xFaDe 0xFaDE 0XFaDe 0xfAdE
query I
SELECT '${hex}'::INT;
----
64222
endloop
# Casting zeros
foreach inttype TINYINT SMALLINT INTEGER BIGINT HUGEINT DECIMAL
query I
SELECT '0'::${inttype};
----
0
endloop
# Casting infinities of various timestamp units
foreach ts timestamp timestamp_ms timestamp_ns timestamp_s timestamptz
query I
SELECT ('infinity'::${ts})::VARCHAR
----
infinity
query I
SELECT ('-infinity'::${ts})::VARCHAR
----
-infinity
query I
SELECT TRY_CAST('infinity' AS ${ts})
----
infinity
query I
SELECT TRY_CAST('-infinity' AS ${ts})
----
-infinity
#ts
endloop

View File

@@ -0,0 +1,44 @@
# name: test/sql/cast/test_try_cast.test
# description: Test try cast
# group: [cast]
statement ok
PRAGMA enable_verification
# TRY_CAST turns a failed cast into NULL
query I
SELECT TRY_CAST('hello' as INTEGER)
----
NULL
# CAST throws an error
statement error
SELECT CAST('hello' as INTEGER)
----
query IIII
SELECT TRY_CAST(3 as BIGINT), CAST(3 AS BIGINT), TRY_CAST(2 as BIGINT), CAST(3 AS INTEGER)
----
3 3 2 3
# not a reserved keyword
statement ok
CREATE TABLE try_cast(try_cast INTEGER);
statement ok
INSERT INTO try_cast VALUES (3);
query I
SELECT try_cast FROM try_cast;
----
3
query I
SELECT try_cast(try_cast as bigint) FROM try_cast;
----
3
query I
SELECT try_cast(try_cast(try_cast as integer) as integer) FROM try_cast;
----
3

View File

@@ -0,0 +1,41 @@
# name: test/sql/cast/timestamp_date_cast.test
# description: Issue #2588: Incorrect result with date conversion
# group: [cast]
statement ok
PRAGMA enable_verification
statement ok
create table test as
select '2021-02-04 19:30:00'::timestamp t;
query I
select *
from test
where (t::date) = '2021-02-04'::date;
----
2021-02-04 19:30:00
query I
select *
from test
where (t::date) = '2021-02-04';
----
2021-02-04 19:30:00
# Check that casts to DATE are not invertible
foreach source TIMESTAMP TIMESTAMP_S TIMESTAMP_MS TIMESTAMP_NS
query I
WITH t AS (
SELECT
'2020-09-13 00:30:00'::${source} AS a,
)
SELECT
a::DATE = '2020-09-13'::DATE,
FROM t;
----
true
endloop