000001 # 2005 June 25 000002 # 000003 # The author disclaims copyright to this source code. In place of 000004 # a legal notice, here is a blessing: 000005 # 000006 # May you do good and not evil. 000007 # May you find forgiveness for yourself and forgive others. 000008 # May you share freely, never taking more than you give. 000009 # 000010 #*********************************************************************** 000011 # This file implements regression tests for SQLite library. The 000012 # focus of this file is testing the CAST operator. 000013 # 000014 # $Id: cast.test,v 1.10 2008/11/06 15:33:04 drh Exp $ 000015 000016 set testdir [file dirname $argv0] 000017 source $testdir/tester.tcl 000018 000019 # Only run these tests if the build includes the CAST operator 000020 ifcapable !cast { 000021 finish_test 000022 return 000023 } 000024 000025 # Tests for the CAST( AS blob), CAST( AS text) and CAST( AS numeric) built-ins 000026 # 000027 ifcapable bloblit { 000028 do_test cast-1.1 { 000029 execsql {SELECT x'616263'} 000030 } abc 000031 do_test cast-1.2 { 000032 execsql {SELECT typeof(x'616263')} 000033 } blob 000034 do_test cast-1.3 { 000035 execsql {SELECT CAST(x'616263' AS text)} 000036 } abc 000037 do_test cast-1.4 { 000038 execsql {SELECT typeof(CAST(x'616263' AS text))} 000039 } text 000040 do_test cast-1.5 { 000041 execsql {SELECT CAST(x'616263' AS numeric)} 000042 } 0 000043 do_test cast-1.6 { 000044 execsql {SELECT typeof(CAST(x'616263' AS numeric))} 000045 } integer 000046 do_test cast-1.7 { 000047 execsql {SELECT CAST(x'616263' AS blob)} 000048 } abc 000049 do_test cast-1.8 { 000050 execsql {SELECT typeof(CAST(x'616263' AS blob))} 000051 } blob 000052 do_test cast-1.9 { 000053 execsql {SELECT CAST(x'616263' AS integer)} 000054 } 0 000055 do_test cast-1.10 { 000056 execsql {SELECT typeof(CAST(x'616263' AS integer))} 000057 } integer 000058 } 000059 do_test cast-1.11 { 000060 execsql {SELECT null} 000061 } {{}} 000062 do_test cast-1.12 { 000063 execsql {SELECT typeof(NULL)} 000064 } null 000065 do_test cast-1.13 { 000066 execsql {SELECT CAST(NULL AS text)} 000067 } {{}} 000068 do_test cast-1.14 { 000069 execsql {SELECT typeof(CAST(NULL AS text))} 000070 } null 000071 do_test cast-1.15 { 000072 execsql {SELECT CAST(NULL AS numeric)} 000073 } {{}} 000074 do_test cast-1.16 { 000075 execsql {SELECT typeof(CAST(NULL AS numeric))} 000076 } null 000077 do_test cast-1.17 { 000078 execsql {SELECT CAST(NULL AS blob)} 000079 } {{}} 000080 do_test cast-1.18 { 000081 execsql {SELECT typeof(CAST(NULL AS blob))} 000082 } null 000083 do_test cast-1.19 { 000084 execsql {SELECT CAST(NULL AS integer)} 000085 } {{}} 000086 do_test cast-1.20 { 000087 execsql {SELECT typeof(CAST(NULL AS integer))} 000088 } null 000089 do_test cast-1.21 { 000090 execsql {SELECT 123} 000091 } {123} 000092 do_test cast-1.22 { 000093 execsql {SELECT typeof(123)} 000094 } integer 000095 do_test cast-1.23 { 000096 execsql {SELECT CAST(123 AS text)} 000097 } {123} 000098 do_test cast-1.24 { 000099 execsql {SELECT typeof(CAST(123 AS text))} 000100 } text 000101 do_test cast-1.25 { 000102 execsql {SELECT CAST(123 AS numeric)} 000103 } 123 000104 do_test cast-1.26 { 000105 execsql {SELECT typeof(CAST(123 AS numeric))} 000106 } integer 000107 do_test cast-1.27 { 000108 execsql {SELECT CAST(123 AS blob)} 000109 } {123} 000110 do_test cast-1.28 { 000111 execsql {SELECT typeof(CAST(123 AS blob))} 000112 } blob 000113 do_test cast-1.29 { 000114 execsql {SELECT CAST(123 AS integer)} 000115 } {123} 000116 do_test cast-1.30 { 000117 execsql {SELECT typeof(CAST(123 AS integer))} 000118 } integer 000119 do_test cast-1.31 { 000120 execsql {SELECT 123.456} 000121 } {123.456} 000122 do_test cast-1.32 { 000123 execsql {SELECT typeof(123.456)} 000124 } real 000125 do_test cast-1.33 { 000126 execsql {SELECT CAST(123.456 AS text)} 000127 } {123.456} 000128 do_test cast-1.34 { 000129 execsql {SELECT typeof(CAST(123.456 AS text))} 000130 } text 000131 do_test cast-1.35 { 000132 execsql {SELECT CAST(123.456 AS numeric)} 000133 } 123.456 000134 do_test cast-1.36 { 000135 execsql {SELECT typeof(CAST(123.456 AS numeric))} 000136 } real 000137 do_test cast-1.37 { 000138 execsql {SELECT CAST(123.456 AS blob)} 000139 } {123.456} 000140 do_test cast-1.38 { 000141 execsql {SELECT typeof(CAST(123.456 AS blob))} 000142 } blob 000143 do_test cast-1.39 { 000144 execsql {SELECT CAST(123.456 AS integer)} 000145 } {123} 000146 do_test cast-1.38 { 000147 execsql {SELECT typeof(CAST(123.456 AS integer))} 000148 } integer 000149 do_test cast-1.41 { 000150 execsql {SELECT '123abc'} 000151 } {123abc} 000152 do_test cast-1.42 { 000153 execsql {SELECT typeof('123abc')} 000154 } text 000155 do_test cast-1.43 { 000156 execsql {SELECT CAST('123abc' AS text)} 000157 } {123abc} 000158 do_test cast-1.44 { 000159 execsql {SELECT typeof(CAST('123abc' AS text))} 000160 } text 000161 do_test cast-1.45 { 000162 execsql {SELECT CAST('123abc' AS numeric)} 000163 } 123 000164 do_test cast-1.46 { 000165 execsql {SELECT typeof(CAST('123abc' AS numeric))} 000166 } integer 000167 do_test cast-1.47 { 000168 execsql {SELECT CAST('123abc' AS blob)} 000169 } {123abc} 000170 do_test cast-1.48 { 000171 execsql {SELECT typeof(CAST('123abc' AS blob))} 000172 } blob 000173 do_test cast-1.49 { 000174 execsql {SELECT CAST('123abc' AS integer)} 000175 } 123 000176 do_test cast-1.50 { 000177 execsql {SELECT typeof(CAST('123abc' AS integer))} 000178 } integer 000179 do_test cast-1.51 { 000180 execsql {SELECT CAST('123.5abc' AS numeric)} 000181 } 123.5 000182 do_test cast-1.53 { 000183 execsql {SELECT CAST('123.5abc' AS integer)} 000184 } 123 000185 000186 do_test cast-1.60 { 000187 execsql {SELECT CAST(null AS REAL)} 000188 } {{}} 000189 do_test cast-1.61 { 000190 execsql {SELECT typeof(CAST(null AS REAL))} 000191 } {null} 000192 do_test cast-1.62 { 000193 execsql {SELECT CAST(1 AS REAL)} 000194 } {1.0} 000195 do_test cast-1.63 { 000196 execsql {SELECT typeof(CAST(1 AS REAL))} 000197 } {real} 000198 do_test cast-1.64 { 000199 execsql {SELECT CAST('1' AS REAL)} 000200 } {1.0} 000201 do_test cast-1.65 { 000202 execsql {SELECT typeof(CAST('1' AS REAL))} 000203 } {real} 000204 do_test cast-1.66 { 000205 execsql {SELECT CAST('abc' AS REAL)} 000206 } {0.0} 000207 do_test cast-1.67 { 000208 execsql {SELECT typeof(CAST('abc' AS REAL))} 000209 } {real} 000210 do_test cast-1.68 { 000211 execsql {SELECT CAST(x'31' AS REAL)} 000212 } {1.0} 000213 do_test cast-1.69 { 000214 execsql {SELECT typeof(CAST(x'31' AS REAL))} 000215 } {real} 000216 000217 000218 # Ticket #1662. Ignore leading spaces in numbers when casting. 000219 # 000220 do_test cast-2.1 { 000221 execsql {SELECT CAST(' 123' AS integer)} 000222 } 123 000223 do_test cast-2.2 { 000224 execsql {SELECT CAST(' -123.456' AS real)} 000225 } -123.456 000226 000227 # ticket #2364. Use full percision integers if possible when casting 000228 # to numeric. Do not fallback to real (and the corresponding 48-bit 000229 # mantissa) unless absolutely necessary. 000230 # 000231 do_test cast-3.1 { 000232 execsql {SELECT CAST(9223372036854774800 AS integer)} 000233 } 9223372036854774800 000234 do_test cast-3.2 { 000235 execsql {SELECT CAST(9223372036854774800 AS numeric)} 000236 } 9223372036854774800 000237 breakpoint 000238 do_realnum_test cast-3.3 { 000239 execsql {SELECT CAST(9223372036854774800 AS real)} 000240 } 9.22337203685477e+18 000241 do_test cast-3.4 { 000242 execsql {SELECT CAST(CAST(9223372036854774800 AS real) AS integer)} 000243 } 9223372036854774784 000244 do_test cast-3.5 { 000245 execsql {SELECT CAST(-9223372036854774800 AS integer)} 000246 } -9223372036854774800 000247 do_test cast-3.6 { 000248 execsql {SELECT CAST(-9223372036854774800 AS numeric)} 000249 } -9223372036854774800 000250 do_realnum_test cast-3.7 { 000251 execsql {SELECT CAST(-9223372036854774800 AS real)} 000252 } -9.22337203685477e+18 000253 do_test cast-3.8 { 000254 execsql {SELECT CAST(CAST(-9223372036854774800 AS real) AS integer)} 000255 } -9223372036854774784 000256 do_test cast-3.11 { 000257 execsql {SELECT CAST('9223372036854774800' AS integer)} 000258 } 9223372036854774800 000259 do_test cast-3.12 { 000260 execsql {SELECT CAST('9223372036854774800' AS numeric)} 000261 } 9223372036854774800 000262 do_realnum_test cast-3.13 { 000263 execsql {SELECT CAST('9223372036854774800' AS real)} 000264 } 9.22337203685477e+18 000265 do_test cast-3.14 { 000266 execsql {SELECT CAST(CAST('9223372036854774800' AS real) AS integer)} 000267 } 9223372036854774784 000268 do_test cast-3.15 { 000269 execsql {SELECT CAST('-9223372036854774800' AS integer)} 000270 } -9223372036854774800 000271 do_test cast-3.16 { 000272 execsql {SELECT CAST('-9223372036854774800' AS numeric)} 000273 } -9223372036854774800 000274 do_realnum_test cast-3.17 { 000275 execsql {SELECT CAST('-9223372036854774800' AS real)} 000276 } -9.22337203685477e+18 000277 do_test cast-3.18 { 000278 execsql {SELECT CAST(CAST('-9223372036854774800' AS real) AS integer)} 000279 } -9223372036854774784 000280 if {[db eval {PRAGMA encoding}]=="UTF-8"} { 000281 do_test cast-3.21 { 000282 execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS integer)} 000283 } 9223372036854774800 000284 do_test cast-3.22 { 000285 execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS numeric)} 000286 } 9223372036854774800 000287 do_realnum_test cast-3.23 { 000288 execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS real)} 000289 } 9.22337203685477e+18 000290 do_test cast-3.24 { 000291 execsql { 000292 SELECT CAST(CAST(x'39323233333732303336383534373734383030' AS real) 000293 AS integer) 000294 } 000295 } 9223372036854774784 000296 } 000297 do_test cast-3.31 { 000298 execsql {SELECT CAST(NULL AS numeric)} 000299 } {{}} 000300 000301 # Test to see if it is possible to trick SQLite into reading past 000302 # the end of a blob when converting it to a number. 000303 do_test cast-3.32.1 { 000304 set blob "1234567890" 000305 set DB [sqlite3_connection_pointer db] 000306 set ::STMT [sqlite3_prepare $DB {SELECT CAST(? AS real)} -1 TAIL] 000307 sqlite3_bind_blob -static $::STMT 1 $blob 5 000308 sqlite3_step $::STMT 000309 } {SQLITE_ROW} 000310 do_test cast-3.32.2 { 000311 sqlite3_column_int $::STMT 0 000312 } {12345} 000313 do_test cast-3.32.3 { 000314 sqlite3_finalize $::STMT 000315 } {SQLITE_OK} 000316 000317 000318 do_test cast-4.1 { 000319 db eval { 000320 CREATE TABLE t1(a); 000321 INSERT INTO t1 VALUES('abc'); 000322 SELECT a, CAST(a AS integer) FROM t1; 000323 } 000324 } {abc 0} 000325 do_test cast-4.2 { 000326 db eval { 000327 SELECT CAST(a AS integer), a FROM t1; 000328 } 000329 } {0 abc} 000330 do_test cast-4.3 { 000331 db eval { 000332 SELECT a, CAST(a AS integer), a FROM t1; 000333 } 000334 } {abc 0 abc} 000335 do_test cast-4.4 { 000336 db eval { 000337 SELECT CAST(a AS integer), a, CAST(a AS real), a FROM t1; 000338 } 000339 } {0 abc 0.0 abc} 000340 000341 # Added 2018-01-26 000342 # 000343 # EVIDENCE-OF: R-48741-32454 If the prefix integer is greater than 000344 # +9223372036854775807 then the result of the cast is exactly 000345 # +9223372036854775807. 000346 do_execsql_test cast-5.1 { 000347 SELECT CAST('9223372036854775808' AS integer); 000348 SELECT CAST(' +000009223372036854775808' AS integer); 000349 SELECT CAST('12345678901234567890123' AS INTEGER); 000350 } {9223372036854775807 9223372036854775807 9223372036854775807} 000351 000352 # EVIDENCE-OF: R-06028-16857 Similarly, if the prefix integer is less 000353 # than -9223372036854775808 then the result of the cast is exactly 000354 # -9223372036854775808. 000355 do_execsql_test cast-5.2 { 000356 SELECT CAST('-9223372036854775808' AS integer); 000357 SELECT CAST('-9223372036854775809' AS integer); 000358 SELECT CAST('-12345678901234567890123' AS INTEGER); 000359 } {-9223372036854775808 -9223372036854775808 -9223372036854775808} 000360 000361 # EVIDENCE-OF: R-33990-33527 When casting to INTEGER, if the text looks 000362 # like a floating point value with an exponent, the exponent will be 000363 # ignored because it is no part of the integer prefix. 000364 # EVIDENCE-OF: R-24225-46995 For example, "(CAST '123e+5' AS INTEGER)" 000365 # results in 123, not in 12300000. 000366 do_execsql_test cast-5.3 { 000367 SELECT CAST('123e+5' AS INTEGER); 000368 SELECT CAST('123e+5' AS NUMERIC); 000369 SELECT CAST('123e+5' AS REAL); 000370 } {123 12300000 12300000.0} 000371 000372 000373 # The following does not have anything to do with the CAST operator, 000374 # but it does deal with affinity transformations. 000375 # 000376 do_execsql_test cast-6.1 { 000377 DROP TABLE IF EXISTS t1; 000378 CREATE TABLE t1(a NUMERIC); 000379 INSERT INTO t1 VALUES 000380 ('9000000000000000001'), 000381 ('9000000000000000001 '), 000382 (' 9000000000000000001'), 000383 (' 9000000000000000001 '); 000384 SELECT * FROM t1; 000385 } {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001} 000386 000387 # 2019-06-07 000388 # https://www.sqlite.org/src/info/4c2d7639f076aa7c 000389 do_execsql_test cast-7.1 { 000390 SELECT CAST('-' AS NUMERIC); 000391 } {0} 000392 do_execsql_test cast-7.2 { 000393 SELECT CAST('-0' AS NUMERIC); 000394 } {0} 000395 do_execsql_test cast-7.3 { 000396 SELECT CAST('+' AS NUMERIC); 000397 } {0} 000398 do_execsql_test cast-7.4 { 000399 SELECT CAST('/' AS NUMERIC); 000400 } {0} 000401 000402 # 2019-06-07 000403 # https://www.sqlite.org/src/info/e8bedb2a184001bb 000404 do_execsql_test cast-7.10 { 000405 SELECT '' - 2851427734582196970; 000406 } {-2851427734582196970} 000407 do_execsql_test cast-7.11 { 000408 SELECT 0 - 2851427734582196970; 000409 } {-2851427734582196970} 000410 do_execsql_test cast-7.12 { 000411 SELECT '' - 1; 000412 } {-1} 000413 000414 # 2019-06-10 000415 # https://www.sqlite.org/src/info/dd6bffbfb6e61db9 000416 # 000417 # EVIDENCE-OF: R-55084-10555 Casting a TEXT or BLOB value into NUMERIC 000418 # yields either an INTEGER or a REAL result. 000419 # 000420 do_execsql_test cast-7.20 { 000421 DROP TABLE IF EXISTS t0; 000422 CREATE TABLE t0 (c0 TEXT); 000423 INSERT INTO t0(c0) VALUES ('1.0'); 000424 SELECT CAST(c0 AS NUMERIC) FROM t0; 000425 } {1} 000426 000427 # 2019-06-10 000428 # https://sqlite.org/src/info/27de823723a41df45af3 000429 # 000430 do_execsql_test cast-7.30 { 000431 SELECT -'.'; 000432 } 0 000433 do_execsql_test cast-7.31 { 000434 SELECT '.'+0; 000435 } 0 000436 do_execsql_test cast-7.32 { 000437 SELECT CAST('.' AS numeric); 000438 } 0 000439 do_execsql_test cast-7.33 { 000440 SELECT -CAST('.' AS numeric); 000441 } 0 000442 000443 # 2019-06-12 000444 # https://www.sqlite.org/src/info/674385aeba91c774 000445 # 000446 do_execsql_test cast-7.40 { 000447 SELECT CAST('-0.0' AS numeric); 000448 } 0 000449 do_execsql_test cast-7.41 { 000450 SELECT CAST('0.0' AS numeric); 000451 } 0 000452 do_execsql_test cast-7.42 { 000453 SELECT CAST('+0.0' AS numeric); 000454 } 0 000455 do_execsql_test cast-7.43 { 000456 SELECT CAST('-1.0' AS numeric); 000457 } -1 000458 000459 ifcapable utf16 { 000460 reset_db 000461 execsql { PRAGMA encoding='utf16' } 000462 000463 do_execsql_test cast-8.1 { 000464 SELECT quote(X'310032003300')==quote(substr(X'310032003300', 1)) 000465 } 1 000466 do_execsql_test cast-8.2 { 000467 SELECT CAST(X'310032003300' AS TEXT) 000468 ==CAST(substr(X'310032003300', 1) AS TEXT) 000469 } 1 000470 } 000471 000472 reset_db 000473 do_execsql_test cast-9.0 { 000474 CREATE TABLE t0(c0); 000475 INSERT INTO t0(c0) VALUES (0); 000476 CREATE VIEW v1(c0, c1) AS 000477 SELECT CAST(0.0 AS NUMERIC), COUNT(*) OVER () FROM t0; 000478 SELECT v1.c0 FROM v1, t0 WHERE v1.c0=0; 000479 } {0.0} 000480 000481 # Set the 2022-12-10 "reopen" of ticket [https://sqlite.org/src/tktview/57c47526c3] 000482 # 000483 do_execsql_test cast-9.1 { 000484 CREATE TABLE dual(dummy TEXT); 000485 INSERT INTO dual VALUES('X'); 000486 SELECT CAST(4 AS NUMERIC); 000487 } {4} 000488 do_execsql_test cast-9.2 { 000489 SELECT CAST(4.0 AS NUMERIC); 000490 } {4.0} 000491 do_execsql_test cast-9.3 { 000492 SELECT CAST(4.5 AS NUMERIC); 000493 } {4.5} 000494 do_execsql_test cast-9.4 { 000495 SELECT x, typeof(x) FROM (SELECT CAST(4 AS NUMERIC) AS x) JOIN dual; 000496 } {4 integer} 000497 do_execsql_test cast-9.5 { 000498 SELECT x, typeof(x) FROM dual CROSS JOIN (SELECT CAST(4 AS NUMERIC) AS x); 000499 } {4 integer} 000500 do_execsql_test cast-9.10 { 000501 SELECT x, typeof(x) FROM (SELECT CAST(4.0 AS NUMERIC) AS x) JOIN dual; 000502 } {4.0 real} 000503 do_execsql_test cast-9.11 { 000504 SELECT x, typeof(x) FROM dual CROSS JOIN (SELECT CAST(4.0 AS NUMERIC) AS x); 000505 } {4.0 real} 000506 do_execsql_test cast-9.12 { 000507 SELECT x, typeof(x) FROM (SELECT CAST(4.5 AS NUMERIC) AS x) JOIN dual; 000508 } {4.5 real} 000509 do_execsql_test cast-9.13 { 000510 SELECT x, typeof(x) FROM dual CROSS JOIN (SELECT CAST(4.5 AS NUMERIC) AS x); 000511 } {4.5 real} 000512 000513 # 2022-12-15 dbsqlfuzz c9ee6f9a0a8b8fefb02cf69de2a8b67ca39525c8 000514 # 000515 # Added a new SQLITE_AFF_FLEXNUM that does not try to convert int to real or 000516 # real to int. 000517 # 000518 do_execsql_test cast-10.1 { 000519 VALUES(CAST(44 AS REAL)),(55); 000520 } {44.0 55} 000521 do_execsql_test cast-10.2 { 000522 SELECT CAST(44 AS REAL) AS 'm' UNION ALL SELECT 55; 000523 } {44.0 55} 000524 do_execsql_test cast-10.3 { 000525 SELECT * FROM (VALUES(CAST(44 AS REAL)),(55)); 000526 } {44.0 55} 000527 do_execsql_test cast-10.4 { 000528 SELECT * FROM (SELECT CAST(44 AS REAL) AS 'm' UNION ALL SELECT 55); 000529 } {44.0 55} 000530 do_execsql_test cast-10.5 { 000531 SELECT * FROM dual CROSS JOIN (VALUES(CAST(44 AS REAL)),(55)); 000532 } {X 44.0 X 55} 000533 do_execsql_test cast-10.6 { 000534 SELECT * FROM dual CROSS JOIN (SELECT CAST(44 AS REAL) AS 'm' 000535 UNION ALL SELECT 55); 000536 } {X 44.0 X 55} 000537 ifcapable vtab { 000538 do_execsql_test cast-10.7 { 000539 DROP VIEW v1; 000540 CREATE VIEW v1 AS SELECT CAST(44 AS REAL) AS 'm' UNION ALL SELECT 55; 000541 SELECT name, type FROM pragma_table_info('v1'); 000542 } {m NUM} 000543 do_execsql_test cast-10.8 { 000544 CREATE VIEW v2 AS VALUES(CAST(44 AS REAL)),(55); 000545 SELECT type FROM pragma_table_info('v2'); 000546 } {NUM} 000547 do_execsql_test cast-10.9 { 000548 SELECT * FROM v1; 000549 } {44.0 55} 000550 do_execsql_test cast-10.10 { 000551 SELECT * FROM v2; 000552 } {44.0 55} 000553 } 000554 000555 finish_test