3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the CAST operator.
14 # $Id: cast.test,v 1.10 2008/11/06 15:33:04 drh Exp $
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
19 # Only run these tests if the build includes the CAST operator
25 # Tests for the CAST( AS blob), CAST( AS text) and CAST( AS numeric) built-ins
29 execsql {SELECT x'616263'}
32 execsql {SELECT typeof(x'616263')}
35 execsql {SELECT CAST(x'616263' AS text)}
38 execsql {SELECT typeof(CAST(x'616263' AS text))}
41 execsql {SELECT CAST(x'616263' AS numeric)}
44 execsql {SELECT typeof(CAST(x'616263' AS numeric))}
47 execsql {SELECT CAST(x'616263' AS blob)}
50 execsql {SELECT typeof(CAST(x'616263' AS blob))}
53 execsql {SELECT CAST(x'616263' AS integer)}
56 execsql {SELECT typeof(CAST(x'616263' AS integer))}
63 execsql {SELECT typeof(NULL)}
66 execsql {SELECT CAST(NULL AS text)}
69 execsql {SELECT typeof(CAST(NULL AS text))}
72 execsql {SELECT CAST(NULL AS numeric)}
75 execsql {SELECT typeof(CAST(NULL AS numeric))}
78 execsql {SELECT CAST(NULL AS blob)}
81 execsql {SELECT typeof(CAST(NULL AS blob))}
84 execsql {SELECT CAST(NULL AS integer)}
87 execsql {SELECT typeof(CAST(NULL AS integer))}
93 execsql {SELECT typeof(123)}
96 execsql {SELECT CAST(123 AS text)}
99 execsql {SELECT typeof(CAST(123 AS text))}
102 execsql {SELECT CAST(123 AS numeric)}
105 execsql {SELECT typeof(CAST(123 AS numeric))}
108 execsql {SELECT CAST(123 AS blob)}
111 execsql {SELECT typeof(CAST(123 AS blob))}
114 execsql {SELECT CAST(123 AS integer)}
117 execsql {SELECT typeof(CAST(123 AS integer))}
120 execsql {SELECT 123.456}
123 execsql {SELECT typeof(123.456)}
126 execsql {SELECT CAST(123.456 AS text)}
129 execsql {SELECT typeof(CAST(123.456 AS text))}
132 execsql {SELECT CAST(123.456 AS numeric)}
135 execsql {SELECT typeof(CAST(123.456 AS numeric))}
138 execsql {SELECT CAST(123.456 AS blob)}
141 execsql {SELECT typeof(CAST(123.456 AS blob))}
144 execsql {SELECT CAST(123.456 AS integer)}
147 execsql {SELECT typeof(CAST(123.456 AS integer))}
150 execsql {SELECT '123abc'}
153 execsql {SELECT typeof('123abc')}
156 execsql {SELECT CAST('123abc' AS text)}
159 execsql {SELECT typeof(CAST('123abc' AS text))}
162 execsql {SELECT CAST('123abc' AS numeric)}
165 execsql {SELECT typeof(CAST('123abc' AS numeric))}
168 execsql {SELECT CAST('123abc' AS blob)}
171 execsql {SELECT typeof(CAST('123abc' AS blob))}
174 execsql {SELECT CAST('123abc' AS integer)}
177 execsql {SELECT typeof(CAST('123abc' AS integer))}
180 execsql {SELECT CAST('123.5abc' AS numeric)}
183 execsql {SELECT CAST('123.5abc' AS integer)}
187 execsql {SELECT CAST(null AS REAL)}
190 execsql {SELECT typeof(CAST(null AS REAL))}
193 execsql {SELECT CAST(1 AS REAL)}
196 execsql {SELECT typeof(CAST(1 AS REAL))}
199 execsql {SELECT CAST('1' AS REAL)}
202 execsql {SELECT typeof(CAST('1' AS REAL))}
205 execsql {SELECT CAST('abc' AS REAL)}
208 execsql {SELECT typeof(CAST('abc' AS REAL))}
211 execsql {SELECT CAST(x'31' AS REAL)}
214 execsql {SELECT typeof(CAST(x'31' AS REAL))}
218 # Ticket #1662. Ignore leading spaces in numbers when casting.
221 execsql {SELECT CAST(' 123' AS integer)}
224 execsql {SELECT CAST(' -123.456' AS real)}
227 # ticket #2364. Use full percision integers if possible when casting
228 # to numeric. Do not fallback to real (and the corresponding 48-bit
229 # mantissa) unless absolutely necessary.
232 execsql {SELECT CAST(9223372036854774800 AS integer)}
233 } 9223372036854774800
235 execsql {SELECT CAST(9223372036854774800 AS numeric)}
236 } 9223372036854774800
237 do_realnum_test cast-3.3 {
238 execsql {SELECT CAST(9223372036854774800 AS real)}
239 } 9.22337203685477e+18
241 execsql {SELECT CAST(CAST(9223372036854774800 AS real) AS integer)}
242 } 9223372036854774784
244 execsql {SELECT CAST(-9223372036854774800 AS integer)}
245 } -9223372036854774800
247 execsql {SELECT CAST(-9223372036854774800 AS numeric)}
248 } -9223372036854774800
249 do_realnum_test cast-3.7 {
250 execsql {SELECT CAST(-9223372036854774800 AS real)}
251 } -9.22337203685477e+18
253 execsql {SELECT CAST(CAST(-9223372036854774800 AS real) AS integer)}
254 } -9223372036854774784
256 execsql {SELECT CAST('9223372036854774800' AS integer)}
257 } 9223372036854774800
259 execsql {SELECT CAST('9223372036854774800' AS numeric)}
260 } 9223372036854774800
261 do_realnum_test cast-3.13 {
262 execsql {SELECT CAST('9223372036854774800' AS real)}
263 } 9.22337203685477e+18
264 ifcapable long_double {
266 execsql {SELECT CAST(CAST('9223372036854774800' AS real) AS integer)}
267 } 9223372036854774784
270 execsql {SELECT CAST('-9223372036854774800' AS integer)}
271 } -9223372036854774800
273 execsql {SELECT CAST('-9223372036854774800' AS numeric)}
274 } -9223372036854774800
275 do_realnum_test cast-3.17 {
276 execsql {SELECT CAST('-9223372036854774800' AS real)}
277 } -9.22337203685477e+18
278 ifcapable long_double {
280 execsql {SELECT CAST(CAST('-9223372036854774800' AS real) AS integer)}
281 } -9223372036854774784
283 if {[db eval {PRAGMA encoding}]=="UTF-8"} {
285 execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS integer)}
286 } 9223372036854774800
288 execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS numeric)}
289 } 9223372036854774800
290 do_realnum_test cast-3.23 {
291 execsql {SELECT CAST(x'39323233333732303336383534373734383030' AS real)}
292 } 9.22337203685477e+18
293 ifcapable long_double {
296 SELECT CAST(CAST(x'39323233333732303336383534373734383030' AS real)
299 } 9223372036854774784
303 execsql {SELECT CAST(NULL AS numeric)}
306 # Test to see if it is possible to trick SQLite into reading past
307 # the end of a blob when converting it to a number.
308 do_test cast-3.32.1 {
309 set blob "1234567890"
310 set DB [sqlite3_connection_pointer db]
311 set ::STMT [sqlite3_prepare $DB {SELECT CAST(? AS real)} -1 TAIL]
312 sqlite3_bind_blob -static $::STMT 1 $blob 5
315 do_test cast-3.32.2 {
316 sqlite3_column_int $::STMT 0
318 do_test cast-3.32.3 {
319 sqlite3_finalize $::STMT
326 INSERT INTO t1 VALUES('abc');
327 SELECT a, CAST(a AS integer) FROM t1;
332 SELECT CAST(a AS integer), a FROM t1;
337 SELECT a, CAST(a AS integer), a FROM t1;
342 SELECT CAST(a AS integer), a, CAST(a AS real), a FROM t1;
348 # EVIDENCE-OF: R-48741-32454 If the prefix integer is greater than
349 # +9223372036854775807 then the result of the cast is exactly
350 # +9223372036854775807.
351 do_execsql_test cast-5.1 {
352 SELECT CAST('9223372036854775808' AS integer);
353 SELECT CAST(' +000009223372036854775808' AS integer);
354 SELECT CAST('12345678901234567890123' AS INTEGER);
355 } {9223372036854775807 9223372036854775807 9223372036854775807}
357 # EVIDENCE-OF: R-06028-16857 Similarly, if the prefix integer is less
358 # than -9223372036854775808 then the result of the cast is exactly
359 # -9223372036854775808.
360 do_execsql_test cast-5.2 {
361 SELECT CAST('-9223372036854775808' AS integer);
362 SELECT CAST('-9223372036854775809' AS integer);
363 SELECT CAST('-12345678901234567890123' AS INTEGER);
364 } {-9223372036854775808 -9223372036854775808 -9223372036854775808}
366 # EVIDENCE-OF: R-33990-33527 When casting to INTEGER, if the text looks
367 # like a floating point value with an exponent, the exponent will be
368 # ignored because it is no part of the integer prefix.
369 # EVIDENCE-OF: R-24225-46995 For example, "(CAST '123e+5' AS INTEGER)"
370 # results in 123, not in 12300000.
371 do_execsql_test cast-5.3 {
372 SELECT CAST('123e+5' AS INTEGER);
373 SELECT CAST('123e+5' AS NUMERIC);
374 SELECT CAST('123e+5' AS REAL);
375 } {123 12300000 12300000.0}
378 # The following does not have anything to do with the CAST operator,
379 # but it does deal with affinity transformations.
381 do_execsql_test cast-6.1 {
382 DROP TABLE IF EXISTS t1;
383 CREATE TABLE t1(a NUMERIC);
384 INSERT INTO t1 VALUES
385 ('9000000000000000001'),
386 ('9000000000000000001 '),
387 (' 9000000000000000001'),
388 (' 9000000000000000001 ');
390 } {9000000000000000001 9000000000000000001 9000000000000000001 9000000000000000001}
393 # https://www.sqlite.org/src/info/4c2d7639f076aa7c
394 do_execsql_test cast-7.1 {
395 SELECT CAST('-' AS NUMERIC);
397 do_execsql_test cast-7.2 {
398 SELECT CAST('-0' AS NUMERIC);
400 do_execsql_test cast-7.3 {
401 SELECT CAST('+' AS NUMERIC);
403 do_execsql_test cast-7.4 {
404 SELECT CAST('/' AS NUMERIC);
408 # https://www.sqlite.org/src/info/e8bedb2a184001bb
409 do_execsql_test cast-7.10 {
410 SELECT '' - 2851427734582196970;
411 } {-2851427734582196970}
412 do_execsql_test cast-7.11 {
413 SELECT 0 - 2851427734582196970;
414 } {-2851427734582196970}
415 do_execsql_test cast-7.12 {
420 # https://www.sqlite.org/src/info/dd6bffbfb6e61db9
422 # EVIDENCE-OF: R-55084-10555 Casting a TEXT or BLOB value into NUMERIC
423 # yields either an INTEGER or a REAL result.
425 do_execsql_test cast-7.20 {
426 DROP TABLE IF EXISTS t0;
427 CREATE TABLE t0 (c0 TEXT);
428 INSERT INTO t0(c0) VALUES ('1.0');
429 SELECT CAST(c0 AS NUMERIC) FROM t0;
433 # https://sqlite.org/src/info/27de823723a41df45af3
435 do_execsql_test cast-7.30 {
438 do_execsql_test cast-7.31 {
441 do_execsql_test cast-7.32 {
442 SELECT CAST('.' AS numeric);
444 do_execsql_test cast-7.33 {
445 SELECT -CAST('.' AS numeric);
449 # https://www.sqlite.org/src/info/674385aeba91c774
451 do_execsql_test cast-7.40 {
452 SELECT CAST('-0.0' AS numeric);
454 do_execsql_test cast-7.41 {
455 SELECT CAST('0.0' AS numeric);
457 do_execsql_test cast-7.42 {
458 SELECT CAST('+0.0' AS numeric);
460 do_execsql_test cast-7.43 {
461 SELECT CAST('-1.0' AS numeric);
466 execsql { PRAGMA encoding='utf16' }
468 do_execsql_test cast-8.1 {
469 SELECT quote(X'310032003300')==quote(substr(X'310032003300', 1))
471 do_execsql_test cast-8.2 {
472 SELECT CAST(X'310032003300' AS TEXT)
473 ==CAST(substr(X'310032003300', 1) AS TEXT)
478 do_execsql_test cast-9.0 {
480 INSERT INTO t0(c0) VALUES (0);
481 CREATE VIEW v1(c0, c1) AS
482 SELECT CAST(0.0 AS NUMERIC), COUNT(*) OVER () FROM t0;
483 SELECT v1.c0 FROM v1, t0 WHERE v1.c0=0;