000001 # 2001 September 15 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 built-in functions. 000013 # 000014 000015 set testdir [file dirname $argv0] 000016 source $testdir/tester.tcl 000017 set testprefix func 000018 000019 # Create a table to work with. 000020 # 000021 do_test func-0.0 { 000022 execsql {CREATE TABLE tbl1(t1 text)} 000023 foreach word {this program is free software} { 000024 execsql "INSERT INTO tbl1 VALUES('$word')" 000025 } 000026 execsql {SELECT t1 FROM tbl1 ORDER BY t1} 000027 } {free is program software this} 000028 do_test func-0.1 { 000029 execsql { 000030 CREATE TABLE t2(a); 000031 INSERT INTO t2 VALUES(1); 000032 INSERT INTO t2 VALUES(NULL); 000033 INSERT INTO t2 VALUES(345); 000034 INSERT INTO t2 VALUES(NULL); 000035 INSERT INTO t2 VALUES(67890); 000036 SELECT * FROM t2; 000037 } 000038 } {1 {} 345 {} 67890} 000039 000040 # Check out the length() function 000041 # 000042 do_test func-1.0 { 000043 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 000044 } {4 2 7 8 4} 000045 do_test func-1.1 { 000046 set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg] 000047 lappend r $msg 000048 } {1 {wrong number of arguments to function length()}} 000049 do_test func-1.2 { 000050 set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg] 000051 lappend r $msg 000052 } {1 {wrong number of arguments to function length()}} 000053 do_test func-1.3 { 000054 execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1) 000055 ORDER BY length(t1)} 000056 } {2 1 4 2 7 1 8 1} 000057 do_test func-1.4 { 000058 execsql {SELECT coalesce(length(a),-1) FROM t2} 000059 } {1 -1 3 -1 5} 000060 000061 # Check out the substr() function 000062 # 000063 do_test func-2.0 { 000064 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 000065 } {fr is pr so th} 000066 do_test func-2.1 { 000067 execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1} 000068 } {r s r o h} 000069 do_test func-2.2 { 000070 execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1} 000071 } {ee {} ogr ftw is} 000072 do_test func-2.3 { 000073 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 000074 } {e s m e s} 000075 do_test func-2.4 { 000076 execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1} 000077 } {e s m e s} 000078 do_test func-2.5 { 000079 execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1} 000080 } {e i a r i} 000081 do_test func-2.6 { 000082 execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1} 000083 } {ee is am re is} 000084 do_test func-2.7 { 000085 execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1} 000086 } {fr {} gr wa th} 000087 do_test func-2.8 { 000088 execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)} 000089 } {this software free program is} 000090 do_test func-2.9 { 000091 execsql {SELECT substr(a,1,1) FROM t2} 000092 } {1 {} 3 {} 6} 000093 do_test func-2.10 { 000094 execsql {SELECT substr(a,2,2) FROM t2} 000095 } {{} {} 45 {} 78} 000096 000097 # Only do the following tests if TCL has UTF-8 capabilities 000098 # 000099 if {"\u1234"!="u1234"} { 000100 000101 # Put some UTF-8 characters in the database 000102 # 000103 do_test func-3.0 { 000104 execsql {DELETE FROM tbl1} 000105 foreach word "contains UTF-8 characters hi\u1234ho" { 000106 execsql "INSERT INTO tbl1 VALUES('$word')" 000107 } 000108 execsql {SELECT t1 FROM tbl1 ORDER BY t1} 000109 } "UTF-8 characters contains hi\u1234ho" 000110 do_test func-3.1 { 000111 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 000112 } {5 10 8 5} 000113 do_test func-3.2 { 000114 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 000115 } {UT ch co hi} 000116 do_test func-3.3 { 000117 execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1} 000118 } "UTF cha con hi\u1234" 000119 do_test func-3.4 { 000120 execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1} 000121 } "TF ha on i\u1234" 000122 do_test func-3.5 { 000123 execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1} 000124 } "TF- har ont i\u1234h" 000125 do_test func-3.6 { 000126 execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1} 000127 } "F- ar nt \u1234h" 000128 do_test func-3.7 { 000129 execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1} 000130 } "-8 ra ta ho" 000131 do_test func-3.8 { 000132 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 000133 } "8 s s o" 000134 do_test func-3.9 { 000135 execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1} 000136 } "F- er in \u1234h" 000137 do_test func-3.10 { 000138 execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1} 000139 } "TF- ter ain i\u1234h" 000140 do_test func-3.99 { 000141 execsql {DELETE FROM tbl1} 000142 foreach word {this program is free software} { 000143 execsql "INSERT INTO tbl1 VALUES('$word')" 000144 } 000145 execsql {SELECT t1 FROM tbl1} 000146 } {this program is free software} 000147 000148 } ;# End \u1234!=u1234 000149 000150 # Test the abs() and round() functions. 000151 # 000152 ifcapable !floatingpoint { 000153 do_test func-4.1 { 000154 execsql { 000155 CREATE TABLE t1(a,b,c); 000156 INSERT INTO t1 VALUES(1,2,3); 000157 INSERT INTO t1 VALUES(2,12345678901234,-1234567890); 000158 INSERT INTO t1 VALUES(3,-2,-5); 000159 } 000160 catchsql {SELECT abs(a,b) FROM t1} 000161 } {1 {wrong number of arguments to function abs()}} 000162 } 000163 ifcapable floatingpoint { 000164 do_test func-4.1 { 000165 execsql { 000166 CREATE TABLE t1(a,b,c); 000167 INSERT INTO t1 VALUES(1,2,3); 000168 INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890); 000169 INSERT INTO t1 VALUES(3,-2,-5); 000170 } 000171 catchsql {SELECT abs(a,b) FROM t1} 000172 } {1 {wrong number of arguments to function abs()}} 000173 } 000174 do_test func-4.2 { 000175 catchsql {SELECT abs() FROM t1} 000176 } {1 {wrong number of arguments to function abs()}} 000177 ifcapable floatingpoint { 000178 do_test func-4.3 { 000179 catchsql {SELECT abs(b) FROM t1 ORDER BY a} 000180 } {0 {2 1.2345678901234 2}} 000181 do_test func-4.4 { 000182 catchsql {SELECT abs(c) FROM t1 ORDER BY a} 000183 } {0 {3 12345.6789 5}} 000184 } 000185 ifcapable !floatingpoint { 000186 if {[working_64bit_int]} { 000187 do_test func-4.3 { 000188 catchsql {SELECT abs(b) FROM t1 ORDER BY a} 000189 } {0 {2 12345678901234 2}} 000190 } 000191 do_test func-4.4 { 000192 catchsql {SELECT abs(c) FROM t1 ORDER BY a} 000193 } {0 {3 1234567890 5}} 000194 } 000195 do_test func-4.4.1 { 000196 execsql {SELECT abs(a) FROM t2} 000197 } {1 {} 345 {} 67890} 000198 do_test func-4.4.2 { 000199 execsql {SELECT abs(t1) FROM tbl1} 000200 } {0.0 0.0 0.0 0.0 0.0} 000201 000202 ifcapable floatingpoint { 000203 do_test func-4.5 { 000204 catchsql {SELECT round(a,b,c) FROM t1} 000205 } {1 {wrong number of arguments to function round()}} 000206 do_test func-4.6 { 000207 catchsql {SELECT round(b,2) FROM t1 ORDER BY b} 000208 } {0 {-2.0 1.23 2.0}} 000209 do_test func-4.7 { 000210 catchsql {SELECT round(b,0) FROM t1 ORDER BY a} 000211 } {0 {2.0 1.0 -2.0}} 000212 do_test func-4.8 { 000213 catchsql {SELECT round(c) FROM t1 ORDER BY a} 000214 } {0 {3.0 -12346.0 -5.0}} 000215 do_test func-4.9 { 000216 catchsql {SELECT round(c,a) FROM t1 ORDER BY a} 000217 } {0 {3.0 -12345.68 -5.0}} 000218 do_test func-4.10 { 000219 catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a} 000220 } {0 {x3.0y x-12345.68y x-5.0y}} 000221 do_test func-4.11 { 000222 catchsql {SELECT round() FROM t1 ORDER BY a} 000223 } {1 {wrong number of arguments to function round()}} 000224 do_test func-4.12 { 000225 execsql {SELECT coalesce(round(a,2),'nil') FROM t2} 000226 } {1.0 nil 345.0 nil 67890.0} 000227 do_test func-4.13 { 000228 execsql {SELECT round(t1,2) FROM tbl1} 000229 } {0.0 0.0 0.0 0.0 0.0} 000230 do_test func-4.14 { 000231 execsql {SELECT typeof(round(5.1,1));} 000232 } {real} 000233 do_test func-4.15 { 000234 execsql {SELECT typeof(round(5.1));} 000235 } {real} 000236 do_test func-4.16 { 000237 catchsql {SELECT round(b,2.0) FROM t1 ORDER BY b} 000238 } {0 {-2.0 1.23 2.0}} 000239 # Verify some values reported on the mailing list. 000240 # Some of these fail on MSVC builds with 64-bit 000241 # long doubles, but not on GCC builds with 80-bit 000242 # long doubles. 000243 for {set i 1} {$i<999} {incr i} { 000244 set x1 [expr 40222.5 + $i] 000245 set x2 [expr 40223.0 + $i] 000246 do_test func-4.17.$i { 000247 execsql {SELECT round($x1);} 000248 } $x2 000249 } 000250 for {set i 1} {$i<999} {incr i} { 000251 set x1 [expr 40222.05 + $i] 000252 set x2 [expr 40222.10 + $i] 000253 do_test func-4.18.$i { 000254 execsql {SELECT round($x1,1);} 000255 } $x2 000256 } 000257 do_test func-4.20 { 000258 execsql {SELECT round(40223.4999999999);} 000259 } {40223.0} 000260 do_test func-4.21 { 000261 execsql {SELECT round(40224.4999999999);} 000262 } {40224.0} 000263 do_test func-4.22 { 000264 execsql {SELECT round(40225.4999999999);} 000265 } {40225.0} 000266 for {set i 1} {$i<10} {incr i} { 000267 do_test func-4.23.$i { 000268 execsql {SELECT round(40223.4999999999,$i);} 000269 } {40223.5} 000270 do_test func-4.24.$i { 000271 execsql {SELECT round(40224.4999999999,$i);} 000272 } {40224.5} 000273 do_test func-4.25.$i { 000274 execsql {SELECT round(40225.4999999999,$i);} 000275 } {40225.5} 000276 } 000277 for {set i 10} {$i<32} {incr i} { 000278 do_test func-4.26.$i { 000279 execsql {SELECT round(40223.4999999999,$i);} 000280 } {40223.4999999999} 000281 do_test func-4.27.$i { 000282 execsql {SELECT round(40224.4999999999,$i);} 000283 } {40224.4999999999} 000284 do_test func-4.28.$i { 000285 execsql {SELECT round(40225.4999999999,$i);} 000286 } {40225.4999999999} 000287 } 000288 do_test func-4.29 { 000289 execsql {SELECT round(1234567890.5);} 000290 } {1234567891.0} 000291 do_test func-4.30 { 000292 execsql {SELECT round(12345678901.5);} 000293 } {12345678902.0} 000294 do_test func-4.31 { 000295 execsql {SELECT round(123456789012.5);} 000296 } {123456789013.0} 000297 do_test func-4.32 { 000298 execsql {SELECT round(1234567890123.5);} 000299 } {1234567890124.0} 000300 do_test func-4.33 { 000301 execsql {SELECT round(12345678901234.5);} 000302 } {12345678901235.0} 000303 do_test func-4.34 { 000304 execsql {SELECT round(1234567890123.35,1);} 000305 } {1234567890123.4} 000306 do_test func-4.35 { 000307 execsql {SELECT round(1234567890123.445,2);} 000308 } {1234567890123.45} 000309 do_test func-4.36 { 000310 execsql {SELECT round(99999999999994.5);} 000311 } {99999999999995.0} 000312 do_test func-4.37 { 000313 execsql {SELECT round(9999999999999.55,1);} 000314 } {9999999999999.6} 000315 do_test func-4.38 { 000316 execsql {SELECT round(9999999999999.556,2);} 000317 } {9999999999999.56} 000318 } 000319 000320 # Test the upper() and lower() functions 000321 # 000322 do_test func-5.1 { 000323 execsql {SELECT upper(t1) FROM tbl1} 000324 } {THIS PROGRAM IS FREE SOFTWARE} 000325 do_test func-5.2 { 000326 execsql {SELECT lower(upper(t1)) FROM tbl1} 000327 } {this program is free software} 000328 do_test func-5.3 { 000329 execsql {SELECT upper(a), lower(a) FROM t2} 000330 } {1 1 {} {} 345 345 {} {} 67890 67890} 000331 ifcapable !icu { 000332 do_test func-5.4 { 000333 catchsql {SELECT upper(a,5) FROM t2} 000334 } {1 {wrong number of arguments to function upper()}} 000335 } 000336 do_test func-5.5 { 000337 catchsql {SELECT upper(*) FROM t2} 000338 } {1 {wrong number of arguments to function upper()}} 000339 000340 # Test the coalesce() and nullif() functions 000341 # 000342 do_test func-6.1 { 000343 execsql {SELECT coalesce(a,'xyz') FROM t2} 000344 } {1 xyz 345 xyz 67890} 000345 do_test func-6.2 { 000346 execsql {SELECT coalesce(upper(a),'nil') FROM t2} 000347 } {1 nil 345 nil 67890} 000348 do_test func-6.3 { 000349 execsql {SELECT coalesce(nullif(1,1),'nil')} 000350 } {nil} 000351 do_test func-6.4 { 000352 execsql {SELECT coalesce(nullif(1,2),'nil')} 000353 } {1} 000354 do_test func-6.5 { 000355 execsql {SELECT coalesce(nullif(1,NULL),'nil')} 000356 } {1} 000357 000358 000359 # Test the last_insert_rowid() function 000360 # 000361 do_test func-7.1 { 000362 execsql {SELECT last_insert_rowid()} 000363 } [db last_insert_rowid] 000364 000365 # Tests for aggregate functions and how they handle NULLs. 000366 # 000367 ifcapable floatingpoint { 000368 do_test func-8.1 { 000369 ifcapable explain { 000370 execsql {EXPLAIN SELECT sum(a) FROM t2;} 000371 } 000372 execsql { 000373 SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2; 000374 } 000375 } {68236 3 22745.33 1 67890 5} 000376 } 000377 ifcapable !floatingpoint { 000378 do_test func-8.1 { 000379 ifcapable explain { 000380 execsql {EXPLAIN SELECT sum(a) FROM t2;} 000381 } 000382 execsql { 000383 SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2; 000384 } 000385 } {68236 3 22745.0 1 67890 5} 000386 } 000387 do_test func-8.2 { 000388 execsql { 000389 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; 000390 } 000391 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 000392 000393 ifcapable tempdb { 000394 do_test func-8.3 { 000395 execsql { 000396 CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 000397 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 000398 } 000399 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 000400 } else { 000401 do_test func-8.3 { 000402 execsql { 000403 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 000404 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 000405 } 000406 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 000407 } 000408 do_test func-8.4 { 000409 execsql { 000410 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 000411 } 000412 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 000413 ifcapable compound { 000414 do_test func-8.5 { 000415 execsql { 000416 SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x 000417 UNION ALL SELECT -9223372036854775807) 000418 } 000419 } {0} 000420 do_test func-8.6 { 000421 execsql { 000422 SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x 000423 UNION ALL SELECT -9223372036854775807) 000424 } 000425 } {integer} 000426 do_test func-8.7 { 000427 execsql { 000428 SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x 000429 UNION ALL SELECT -9223372036854775807) 000430 } 000431 } {real} 000432 ifcapable floatingpoint { 000433 do_test func-8.8 { 000434 execsql { 000435 SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x 000436 UNION ALL SELECT -9223372036850000000) 000437 } 000438 } {1} 000439 } 000440 ifcapable !floatingpoint { 000441 do_test func-8.8 { 000442 execsql { 000443 SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x 000444 UNION ALL SELECT -9223372036850000000) 000445 } 000446 } {1} 000447 } 000448 } 000449 000450 # How do you test the random() function in a meaningful, deterministic way? 000451 # 000452 do_test func-9.1 { 000453 execsql { 000454 SELECT random() is not null; 000455 } 000456 } {1} 000457 do_test func-9.2 { 000458 execsql { 000459 SELECT typeof(random()); 000460 } 000461 } {integer} 000462 do_test func-9.3 { 000463 execsql { 000464 SELECT randomblob(32) is not null; 000465 } 000466 } {1} 000467 do_test func-9.4 { 000468 execsql { 000469 SELECT typeof(randomblob(32)); 000470 } 000471 } {blob} 000472 do_test func-9.5 { 000473 execsql { 000474 SELECT length(randomblob(32)), length(randomblob(-5)), 000475 length(randomblob(2000)) 000476 } 000477 } {32 1 2000} 000478 000479 # The "hex()" function was added in order to be able to render blobs 000480 # generated by randomblob(). So this seems like a good place to test 000481 # hex(). 000482 # 000483 ifcapable bloblit { 000484 do_test func-9.10 { 000485 execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')} 000486 } {00112233445566778899AABBCCDDEEFF} 000487 } 000488 set encoding [db one {PRAGMA encoding}] 000489 if {$encoding=="UTF-16le"} { 000490 do_test func-9.11-utf16le { 000491 execsql {SELECT hex(replace('abcdefg','ef','12'))} 000492 } {6100620063006400310032006700} 000493 do_test func-9.12-utf16le { 000494 execsql {SELECT hex(replace('abcdefg','','12'))} 000495 } {6100620063006400650066006700} 000496 do_test func-9.13-utf16le { 000497 execsql {SELECT hex(replace('aabcdefg','a','aaa'))} 000498 } {610061006100610061006100620063006400650066006700} 000499 } elseif {$encoding=="UTF-8"} { 000500 do_test func-9.11-utf8 { 000501 execsql {SELECT hex(replace('abcdefg','ef','12'))} 000502 } {61626364313267} 000503 do_test func-9.12-utf8 { 000504 execsql {SELECT hex(replace('abcdefg','','12'))} 000505 } {61626364656667} 000506 do_test func-9.13-utf8 { 000507 execsql {SELECT hex(replace('aabcdefg','a','aaa'))} 000508 } {616161616161626364656667} 000509 } 000510 000511 # Use the "sqlite_register_test_function" TCL command which is part of 000512 # the text fixture in order to verify correct operation of some of 000513 # the user-defined SQL function APIs that are not used by the built-in 000514 # functions. 000515 # 000516 set ::DB [sqlite3_connection_pointer db] 000517 sqlite_register_test_function $::DB testfunc 000518 do_test func-10.1 { 000519 catchsql { 000520 SELECT testfunc(NULL,NULL); 000521 } 000522 } {1 {first argument should be one of: int int64 string double null value}} 000523 do_test func-10.2 { 000524 execsql { 000525 SELECT testfunc( 000526 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000527 'int', 1234 000528 ); 000529 } 000530 } {1234} 000531 do_test func-10.3 { 000532 execsql { 000533 SELECT testfunc( 000534 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000535 'string', NULL 000536 ); 000537 } 000538 } {{}} 000539 000540 ifcapable floatingpoint { 000541 do_test func-10.4 { 000542 execsql { 000543 SELECT testfunc( 000544 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000545 'double', 1.234 000546 ); 000547 } 000548 } {1.234} 000549 do_test func-10.5 { 000550 execsql { 000551 SELECT testfunc( 000552 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000553 'int', 1234, 000554 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000555 'string', NULL, 000556 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000557 'double', 1.234, 000558 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000559 'int', 1234, 000560 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000561 'string', NULL, 000562 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 000563 'double', 1.234 000564 ); 000565 } 000566 } {1.234} 000567 } 000568 000569 # Test the built-in sqlite_version(*) SQL function. 000570 # 000571 do_test func-11.1 { 000572 execsql { 000573 SELECT sqlite_version(*); 000574 } 000575 } [sqlite3 -version] 000576 000577 # Test that destructors passed to sqlite3 by calls to sqlite3_result_text() 000578 # etc. are called. These tests use two special user-defined functions 000579 # (implemented in func.c) only available in test builds. 000580 # 000581 # Function test_destructor() takes one argument and returns a copy of the 000582 # text form of that argument. A destructor is associated with the return 000583 # value. Function test_destructor_count() returns the number of outstanding 000584 # destructor calls for values returned by test_destructor(). 000585 # 000586 if {[db eval {PRAGMA encoding}]=="UTF-8"} { 000587 do_test func-12.1-utf8 { 000588 execsql { 000589 SELECT test_destructor('hello world'), test_destructor_count(); 000590 } 000591 } {{hello world} 1} 000592 } else { 000593 ifcapable {utf16} { 000594 do_test func-12.1-utf16 { 000595 execsql { 000596 SELECT test_destructor16('hello world'), test_destructor_count(); 000597 } 000598 } {{hello world} 1} 000599 } 000600 } 000601 do_test func-12.2 { 000602 execsql { 000603 SELECT test_destructor_count(); 000604 } 000605 } {0} 000606 do_test func-12.3 { 000607 execsql { 000608 SELECT test_destructor('hello')||' world' 000609 } 000610 } {{hello world}} 000611 do_test func-12.4 { 000612 execsql { 000613 SELECT test_destructor_count(); 000614 } 000615 } {0} 000616 do_test func-12.5 { 000617 execsql { 000618 CREATE TABLE t4(x); 000619 INSERT INTO t4 VALUES(test_destructor('hello')); 000620 INSERT INTO t4 VALUES(test_destructor('world')); 000621 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4; 000622 } 000623 } {hello world} 000624 do_test func-12.6 { 000625 execsql { 000626 SELECT test_destructor_count(); 000627 } 000628 } {0} 000629 do_test func-12.7 { 000630 execsql { 000631 DROP TABLE t4; 000632 } 000633 } {} 000634 000635 000636 # Test that the auxdata API for scalar functions works. This test uses 000637 # a special user-defined function only available in test builds, 000638 # test_auxdata(). Function test_auxdata() takes any number of arguments. 000639 do_test func-13.1 { 000640 execsql { 000641 SELECT test_auxdata('hello world'); 000642 } 000643 } {0} 000644 000645 do_test func-13.2 { 000646 execsql { 000647 CREATE TABLE t4(a, b); 000648 INSERT INTO t4 VALUES('abc', 'def'); 000649 INSERT INTO t4 VALUES('ghi', 'jkl'); 000650 } 000651 } {} 000652 do_test func-13.3 { 000653 execsql { 000654 SELECT test_auxdata('hello world') FROM t4; 000655 } 000656 } {0 1} 000657 do_test func-13.4 { 000658 execsql { 000659 SELECT test_auxdata('hello world', 123) FROM t4; 000660 } 000661 } {{0 0} {1 1}} 000662 do_test func-13.5 { 000663 execsql { 000664 SELECT test_auxdata('hello world', a) FROM t4; 000665 } 000666 } {{0 0} {1 0}} 000667 do_test func-13.6 { 000668 execsql { 000669 SELECT test_auxdata('hello'||'world', a) FROM t4; 000670 } 000671 } {{0 0} {1 0}} 000672 000673 # Test that auxilary data is preserved between calls for SQL variables. 000674 do_test func-13.7 { 000675 set DB [sqlite3_connection_pointer db] 000676 set sql "SELECT test_auxdata( ? , a ) FROM t4;" 000677 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 000678 sqlite3_bind_text $STMT 1 hello\000 -1 000679 set res [list] 000680 while { "SQLITE_ROW"==[sqlite3_step $STMT] } { 000681 lappend res [sqlite3_column_text $STMT 0] 000682 } 000683 lappend res [sqlite3_finalize $STMT] 000684 } {{0 0} {1 0} SQLITE_OK} 000685 000686 # Test that auxiliary data is discarded when a statement is reset. 000687 do_execsql_test 13.8.1 { 000688 SELECT test_auxdata('constant') FROM t4; 000689 } {0 1} 000690 do_execsql_test 13.8.2 { 000691 SELECT test_auxdata('constant') FROM t4; 000692 } {0 1} 000693 db cache flush 000694 do_execsql_test 13.8.3 { 000695 SELECT test_auxdata('constant') FROM t4; 000696 } {0 1} 000697 set V "one" 000698 do_execsql_test 13.8.4 { 000699 SELECT test_auxdata($V), $V FROM t4; 000700 } {0 one 1 one} 000701 set V "two" 000702 do_execsql_test 13.8.5 { 000703 SELECT test_auxdata($V), $V FROM t4; 000704 } {0 two 1 two} 000705 db cache flush 000706 set V "three" 000707 do_execsql_test 13.8.6 { 000708 SELECT test_auxdata($V), $V FROM t4; 000709 } {0 three 1 three} 000710 000711 000712 # Make sure that a function with a very long name is rejected 000713 do_test func-14.1 { 000714 catch { 000715 db function [string repeat X 254] {return "hello"} 000716 } 000717 } {0} 000718 do_test func-14.2 { 000719 catch { 000720 db function [string repeat X 256] {return "hello"} 000721 } 000722 } {1} 000723 000724 do_test func-15.1 { 000725 catchsql {select test_error(NULL)} 000726 } {1 {}} 000727 do_test func-15.2 { 000728 catchsql {select test_error('this is the error message')} 000729 } {1 {this is the error message}} 000730 do_test func-15.3 { 000731 catchsql {select test_error('this is the error message',12)} 000732 } {1 {this is the error message}} 000733 do_test func-15.4 { 000734 db errorcode 000735 } {12} 000736 000737 # Test the quote function for BLOB and NULL values. 000738 do_test func-16.1 { 000739 execsql { 000740 CREATE TABLE tbl2(a, b); 000741 } 000742 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL] 000743 sqlite3_bind_blob $::STMT 1 abc 3 000744 sqlite3_step $::STMT 000745 sqlite3_finalize $::STMT 000746 execsql { 000747 SELECT quote(a), quote(b) FROM tbl2; 000748 } 000749 } {X'616263' NULL} 000750 000751 # Correctly handle function error messages that include %. Ticket #1354 000752 # 000753 do_test func-17.1 { 000754 proc testfunc1 args {error "Error %d with %s percents %p"} 000755 db function testfunc1 ::testfunc1 000756 catchsql { 000757 SELECT testfunc1(1,2,3); 000758 } 000759 } {1 {Error %d with %s percents %p}} 000760 000761 # The SUM function should return integer results when all inputs are integer. 000762 # 000763 do_test func-18.1 { 000764 execsql { 000765 CREATE TABLE t5(x); 000766 INSERT INTO t5 VALUES(1); 000767 INSERT INTO t5 VALUES(-99); 000768 INSERT INTO t5 VALUES(10000); 000769 SELECT sum(x) FROM t5; 000770 } 000771 } {9902} 000772 ifcapable floatingpoint { 000773 do_test func-18.2 { 000774 execsql { 000775 INSERT INTO t5 VALUES(0.0); 000776 SELECT sum(x) FROM t5; 000777 } 000778 } {9902.0} 000779 } 000780 000781 # The sum of nothing is NULL. But the sum of all NULLs is NULL. 000782 # 000783 # The TOTAL of nothing is 0.0. 000784 # 000785 do_test func-18.3 { 000786 execsql { 000787 DELETE FROM t5; 000788 SELECT sum(x), total(x) FROM t5; 000789 } 000790 } {{} 0.0} 000791 do_test func-18.4 { 000792 execsql { 000793 INSERT INTO t5 VALUES(NULL); 000794 SELECT sum(x), total(x) FROM t5 000795 } 000796 } {{} 0.0} 000797 do_test func-18.5 { 000798 execsql { 000799 INSERT INTO t5 VALUES(NULL); 000800 SELECT sum(x), total(x) FROM t5 000801 } 000802 } {{} 0.0} 000803 do_test func-18.6 { 000804 execsql { 000805 INSERT INTO t5 VALUES(123); 000806 SELECT sum(x), total(x) FROM t5 000807 } 000808 } {123 123.0} 000809 000810 # Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes 000811 # an error. The non-standard TOTAL() function continues to give a helpful 000812 # result. 000813 # 000814 do_test func-18.10 { 000815 execsql { 000816 CREATE TABLE t6(x INTEGER); 000817 INSERT INTO t6 VALUES(1); 000818 INSERT INTO t6 VALUES(1<<62); 000819 SELECT sum(x) - ((1<<62)+1) from t6; 000820 } 000821 } 0 000822 do_test func-18.11 { 000823 execsql { 000824 SELECT typeof(sum(x)) FROM t6 000825 } 000826 } integer 000827 ifcapable floatingpoint { 000828 do_test func-18.12 { 000829 catchsql { 000830 INSERT INTO t6 VALUES(1<<62); 000831 SELECT sum(x) - ((1<<62)*2.0+1) from t6; 000832 } 000833 } {1 {integer overflow}} 000834 do_test func-18.13 { 000835 execsql { 000836 SELECT total(x) - ((1<<62)*2.0+1) FROM t6 000837 } 000838 } 0.0 000839 } 000840 ifcapable !floatingpoint { 000841 do_test func-18.12 { 000842 catchsql { 000843 INSERT INTO t6 VALUES(1<<62); 000844 SELECT sum(x) - ((1<<62)*2+1) from t6; 000845 } 000846 } {1 {integer overflow}} 000847 do_test func-18.13 { 000848 execsql { 000849 SELECT total(x) - ((1<<62)*2+1) FROM t6 000850 } 000851 } 0.0 000852 } 000853 if {[working_64bit_int]} { 000854 do_test func-18.14 { 000855 execsql { 000856 SELECT sum(-9223372036854775805); 000857 } 000858 } -9223372036854775805 000859 } 000860 ifcapable compound&&subquery { 000861 000862 do_test func-18.15 { 000863 catchsql { 000864 SELECT sum(x) FROM 000865 (SELECT 9223372036854775807 AS x UNION ALL 000866 SELECT 10 AS x); 000867 } 000868 } {1 {integer overflow}} 000869 if {[working_64bit_int]} { 000870 do_test func-18.16 { 000871 catchsql { 000872 SELECT sum(x) FROM 000873 (SELECT 9223372036854775807 AS x UNION ALL 000874 SELECT -10 AS x); 000875 } 000876 } {0 9223372036854775797} 000877 do_test func-18.17 { 000878 catchsql { 000879 SELECT sum(x) FROM 000880 (SELECT -9223372036854775807 AS x UNION ALL 000881 SELECT 10 AS x); 000882 } 000883 } {0 -9223372036854775797} 000884 } 000885 do_test func-18.18 { 000886 catchsql { 000887 SELECT sum(x) FROM 000888 (SELECT -9223372036854775807 AS x UNION ALL 000889 SELECT -10 AS x); 000890 } 000891 } {1 {integer overflow}} 000892 do_test func-18.19 { 000893 catchsql { 000894 SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x); 000895 } 000896 } {0 -1} 000897 do_test func-18.20 { 000898 catchsql { 000899 SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x); 000900 } 000901 } {0 1} 000902 do_test func-18.21 { 000903 catchsql { 000904 SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x); 000905 } 000906 } {0 -1} 000907 do_test func-18.22 { 000908 catchsql { 000909 SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x); 000910 } 000911 } {0 1} 000912 000913 } ;# ifcapable compound&&subquery 000914 000915 # Integer overflow on abs() 000916 # 000917 if {[working_64bit_int]} { 000918 do_test func-18.31 { 000919 catchsql { 000920 SELECT abs(-9223372036854775807); 000921 } 000922 } {0 9223372036854775807} 000923 } 000924 do_test func-18.32 { 000925 catchsql { 000926 SELECT abs(-9223372036854775807-1); 000927 } 000928 } {1 {integer overflow}} 000929 000930 # The MATCH function exists but is only a stub and always throws an error. 000931 # 000932 do_test func-19.1 { 000933 execsql { 000934 SELECT match(a,b) FROM t1 WHERE 0; 000935 } 000936 } {} 000937 do_test func-19.2 { 000938 catchsql { 000939 SELECT 'abc' MATCH 'xyz'; 000940 } 000941 } {1 {unable to use function MATCH in the requested context}} 000942 do_test func-19.3 { 000943 catchsql { 000944 SELECT 'abc' NOT MATCH 'xyz'; 000945 } 000946 } {1 {unable to use function MATCH in the requested context}} 000947 do_test func-19.4 { 000948 catchsql { 000949 SELECT match(1,2,3); 000950 } 000951 } {1 {wrong number of arguments to function match()}} 000952 000953 # Soundex tests. 000954 # 000955 if {![catch {db eval {SELECT soundex('hello')}}]} { 000956 set i 0 000957 foreach {name sdx} { 000958 euler E460 000959 EULER E460 000960 Euler E460 000961 ellery E460 000962 gauss G200 000963 ghosh G200 000964 hilbert H416 000965 Heilbronn H416 000966 knuth K530 000967 kant K530 000968 Lloyd L300 000969 LADD L300 000970 Lukasiewicz L222 000971 Lissajous L222 000972 A A000 000973 12345 ?000 000974 } { 000975 incr i 000976 do_test func-20.$i { 000977 execsql {SELECT soundex($name)} 000978 } $sdx 000979 } 000980 } 000981 000982 # Tests of the REPLACE function. 000983 # 000984 do_test func-21.1 { 000985 catchsql { 000986 SELECT replace(1,2); 000987 } 000988 } {1 {wrong number of arguments to function replace()}} 000989 do_test func-21.2 { 000990 catchsql { 000991 SELECT replace(1,2,3,4); 000992 } 000993 } {1 {wrong number of arguments to function replace()}} 000994 do_test func-21.3 { 000995 execsql { 000996 SELECT typeof(replace("This is the main test string", NULL, "ALT")); 000997 } 000998 } {null} 000999 do_test func-21.4 { 001000 execsql { 001001 SELECT typeof(replace(NULL, "main", "ALT")); 001002 } 001003 } {null} 001004 do_test func-21.5 { 001005 execsql { 001006 SELECT typeof(replace("This is the main test string", "main", NULL)); 001007 } 001008 } {null} 001009 do_test func-21.6 { 001010 execsql { 001011 SELECT replace("This is the main test string", "main", "ALT"); 001012 } 001013 } {{This is the ALT test string}} 001014 do_test func-21.7 { 001015 execsql { 001016 SELECT replace("This is the main test string", "main", "larger-main"); 001017 } 001018 } {{This is the larger-main test string}} 001019 do_test func-21.8 { 001020 execsql { 001021 SELECT replace("aaaaaaa", "a", "0123456789"); 001022 } 001023 } {0123456789012345678901234567890123456789012345678901234567890123456789} 001024 001025 ifcapable tclvar { 001026 do_test func-21.9 { 001027 # Attempt to exploit a buffer-overflow that at one time existed 001028 # in the REPLACE function. 001029 set ::str "[string repeat A 29998]CC[string repeat A 35537]" 001030 set ::rep [string repeat B 65536] 001031 execsql { 001032 SELECT LENGTH(REPLACE($::str, 'C', $::rep)); 001033 } 001034 } [expr 29998 + 2*65536 + 35537] 001035 } 001036 001037 # Tests for the TRIM, LTRIM and RTRIM functions. 001038 # 001039 do_test func-22.1 { 001040 catchsql {SELECT trim(1,2,3)} 001041 } {1 {wrong number of arguments to function trim()}} 001042 do_test func-22.2 { 001043 catchsql {SELECT ltrim(1,2,3)} 001044 } {1 {wrong number of arguments to function ltrim()}} 001045 do_test func-22.3 { 001046 catchsql {SELECT rtrim(1,2,3)} 001047 } {1 {wrong number of arguments to function rtrim()}} 001048 do_test func-22.4 { 001049 execsql {SELECT trim(' hi ');} 001050 } {hi} 001051 do_test func-22.5 { 001052 execsql {SELECT ltrim(' hi ');} 001053 } {{hi }} 001054 do_test func-22.6 { 001055 execsql {SELECT rtrim(' hi ');} 001056 } {{ hi}} 001057 do_test func-22.7 { 001058 execsql {SELECT trim(' hi ','xyz');} 001059 } {{ hi }} 001060 do_test func-22.8 { 001061 execsql {SELECT ltrim(' hi ','xyz');} 001062 } {{ hi }} 001063 do_test func-22.9 { 001064 execsql {SELECT rtrim(' hi ','xyz');} 001065 } {{ hi }} 001066 do_test func-22.10 { 001067 execsql {SELECT trim('xyxzy hi zzzy','xyz');} 001068 } {{ hi }} 001069 do_test func-22.11 { 001070 execsql {SELECT ltrim('xyxzy hi zzzy','xyz');} 001071 } {{ hi zzzy}} 001072 do_test func-22.12 { 001073 execsql {SELECT rtrim('xyxzy hi zzzy','xyz');} 001074 } {{xyxzy hi }} 001075 do_test func-22.13 { 001076 execsql {SELECT trim(' hi ','');} 001077 } {{ hi }} 001078 if {[db one {PRAGMA encoding}]=="UTF-8"} { 001079 do_test func-22.14 { 001080 execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))} 001081 } {F48FBFBF6869} 001082 do_test func-22.15 { 001083 execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61', 001084 x'6162e1bfbfc280f48fbfbf'))} 001085 } {6869} 001086 do_test func-22.16 { 001087 execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));} 001088 } {CEB2CEB3} 001089 } 001090 do_test func-22.20 { 001091 execsql {SELECT typeof(trim(NULL));} 001092 } {null} 001093 do_test func-22.21 { 001094 execsql {SELECT typeof(trim(NULL,'xyz'));} 001095 } {null} 001096 do_test func-22.22 { 001097 execsql {SELECT typeof(trim('hello',NULL));} 001098 } {null} 001099 001100 # This is to test the deprecated sqlite3_aggregate_count() API. 001101 # 001102 ifcapable deprecated { 001103 do_test func-23.1 { 001104 sqlite3_create_aggregate db 001105 execsql { 001106 SELECT legacy_count() FROM t6; 001107 } 001108 } {3} 001109 } 001110 001111 # The group_concat() function. 001112 # 001113 do_test func-24.1 { 001114 execsql { 001115 SELECT group_concat(t1) FROM tbl1 001116 } 001117 } {this,program,is,free,software} 001118 do_test func-24.2 { 001119 execsql { 001120 SELECT group_concat(t1,' ') FROM tbl1 001121 } 001122 } {{this program is free software}} 001123 do_test func-24.3 { 001124 execsql { 001125 SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1 001126 } 001127 } {{this 2 program 3 is 4 free 5 software}} 001128 do_test func-24.4 { 001129 execsql { 001130 SELECT group_concat(NULL,t1) FROM tbl1 001131 } 001132 } {{}} 001133 do_test func-24.5 { 001134 execsql { 001135 SELECT group_concat(t1,NULL) FROM tbl1 001136 } 001137 } {thisprogramisfreesoftware} 001138 do_test func-24.6 { 001139 execsql { 001140 SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 001141 } 001142 } {BEGIN-this,program,is,free,software} 001143 001144 # Ticket #3179: Make sure aggregate functions can take many arguments. 001145 # None of the built-in aggregates do this, so use the md5sum() from the 001146 # test extensions. 001147 # 001148 unset -nocomplain midargs 001149 set midargs {} 001150 unset -nocomplain midres 001151 set midres {} 001152 unset -nocomplain result 001153 for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} { 001154 append midargs ,'/$i' 001155 append midres /$i 001156 set result [md5 \ 001157 "this${midres}program${midres}is${midres}free${midres}software${midres}"] 001158 set sql "SELECT md5sum(t1$midargs) FROM tbl1" 001159 do_test func-24.7.$i { 001160 db eval $::sql 001161 } $result 001162 } 001163 001164 # Ticket #3806. If the initial string in a group_concat is an empty 001165 # string, the separator that follows should still be present. 001166 # 001167 do_test func-24.8 { 001168 execsql { 001169 SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1 001170 } 001171 } {,program,is,free,software} 001172 do_test func-24.9 { 001173 execsql { 001174 SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1 001175 } 001176 } {,,,,software} 001177 001178 # Ticket #3923. Initial empty strings have a separator. But initial 001179 # NULLs do not. 001180 # 001181 do_test func-24.10 { 001182 execsql { 001183 SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1 001184 } 001185 } {program,is,free,software} 001186 do_test func-24.11 { 001187 execsql { 001188 SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1 001189 } 001190 } {software} 001191 do_test func-24.12 { 001192 execsql { 001193 SELECT group_concat(CASE t1 WHEN 'this' THEN '' 001194 WHEN 'program' THEN null ELSE t1 END) FROM tbl1 001195 } 001196 } {,is,free,software} 001197 # Tests to verify ticket http://www.sqlite.org/src/tktview/55746f9e65f8587c0 001198 do_test func-24.13 { 001199 execsql { 001200 SELECT typeof(group_concat(x)) FROM (SELECT '' AS x); 001201 } 001202 } {text} 001203 do_test func-24.14 { 001204 execsql { 001205 SELECT typeof(group_concat(x,'')) 001206 FROM (SELECT '' AS x UNION ALL SELECT ''); 001207 } 001208 } {text} 001209 001210 001211 # Use the test_isolation function to make sure that type conversions 001212 # on function arguments do not effect subsequent arguments. 001213 # 001214 do_test func-25.1 { 001215 execsql {SELECT test_isolation(t1,t1) FROM tbl1} 001216 } {this program is free software} 001217 001218 # Try to misuse the sqlite3_create_function() interface. Verify that 001219 # errors are returned. 001220 # 001221 do_test func-26.1 { 001222 abuse_create_function db 001223 } {} 001224 001225 # The previous test (func-26.1) registered a function with a very long 001226 # function name that takes many arguments and always returns NULL. Verify 001227 # that this function works correctly. 001228 # 001229 do_test func-26.2 { 001230 set a {} 001231 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} { 001232 lappend a $i 001233 } 001234 db eval " 001235 SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]); 001236 " 001237 } {{}} 001238 do_test func-26.3 { 001239 set a {} 001240 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} { 001241 lappend a $i 001242 } 001243 catchsql " 001244 SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]); 001245 " 001246 } {1 {too many arguments on function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789}} 001247 do_test func-26.4 { 001248 set a {} 001249 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} { 001250 lappend a $i 001251 } 001252 catchsql " 001253 SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789([join $a ,]); 001254 " 001255 } {1 {wrong number of arguments to function nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789()}} 001256 do_test func-26.5 { 001257 catchsql " 001258 SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12345678a(0); 001259 " 001260 } {1 {no such function: nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12345678a}} 001261 do_test func-26.6 { 001262 catchsql " 001263 SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789a(0); 001264 " 001265 } {1 {no such function: nullx_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789a}} 001266 001267 do_test func-27.1 { 001268 catchsql {SELECT coalesce()} 001269 } {1 {wrong number of arguments to function coalesce()}} 001270 do_test func-27.2 { 001271 catchsql {SELECT coalesce(1)} 001272 } {1 {wrong number of arguments to function coalesce()}} 001273 do_test func-27.3 { 001274 catchsql {SELECT coalesce(1,2)} 001275 } {0 1} 001276 001277 # Ticket 2d401a94287b5 001278 # Unknown function in a DEFAULT expression causes a segfault. 001279 # 001280 do_test func-28.1 { 001281 db eval { 001282 CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1))); 001283 } 001284 catchsql { 001285 INSERT INTO t28(x) VALUES(1); 001286 } 001287 } {1 {unknown function: nosuchfunc()}} 001288 001289 # Verify that the length() and typeof() functions do not actually load 001290 # the content of their argument. 001291 # 001292 do_test func-29.1 { 001293 db eval { 001294 CREATE TABLE t29(id INTEGER PRIMARY KEY, x, y); 001295 INSERT INTO t29 VALUES(1, 2, 3), (2, NULL, 4), (3, 4.5, 5); 001296 INSERT INTO t29 VALUES(4, randomblob(1000000), 6); 001297 INSERT INTO t29 VALUES(5, "hello", 7); 001298 } 001299 db close 001300 sqlite3 db test.db 001301 sqlite3_db_status db CACHE_MISS 1 001302 db eval {SELECT typeof(x), length(x), typeof(y) FROM t29 ORDER BY id} 001303 } {integer 1 integer null {} integer real 3 integer blob 1000000 integer text 5 integer} 001304 do_test func-29.2 { 001305 set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] 001306 if {$x<5} {set x 1} 001307 set x 001308 } {1} 001309 do_test func-29.3 { 001310 db close 001311 sqlite3 db test.db 001312 sqlite3_db_status db CACHE_MISS 1 001313 db eval {SELECT typeof(+x) FROM t29 ORDER BY id} 001314 } {integer null real blob text} 001315 if {[permutation] != "mmap"} { 001316 ifcapable !direct_read { 001317 do_test func-29.4 { 001318 set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] 001319 if {$x>100} {set x many} 001320 set x 001321 } {many} 001322 } 001323 } 001324 do_test func-29.5 { 001325 db close 001326 sqlite3 db test.db 001327 sqlite3_db_status db CACHE_MISS 1 001328 db eval {SELECT sum(length(x)) FROM t29} 001329 } {1000009} 001330 do_test func-29.6 { 001331 set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] 001332 if {$x<5} {set x 1} 001333 set x 001334 } {1} 001335 001336 # The OP_Column opcode has an optimization that avoids loading content 001337 # for fields with content-length=0 when the content offset is on an overflow 001338 # page. Make sure the optimization works. 001339 # 001340 do_execsql_test func-29.10 { 001341 CREATE TABLE t29b(a,b,c,d,e,f,g,h,i); 001342 INSERT INTO t29b 001343 VALUES(1, hex(randomblob(2000)), null, 0, 1, '', zeroblob(0),'x',x'01'); 001344 SELECT typeof(c), typeof(d), typeof(e), typeof(f), 001345 typeof(g), typeof(h), typeof(i) FROM t29b; 001346 } {null integer integer text blob text blob} 001347 do_execsql_test func-29.11 { 001348 SELECT length(f), length(g), length(h), length(i) FROM t29b; 001349 } {0 0 1 1} 001350 do_execsql_test func-29.12 { 001351 SELECT quote(f), quote(g), quote(h), quote(i) FROM t29b; 001352 } {'' X'' 'x' X'01'} 001353 001354 # EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric 001355 # unicode code point corresponding to the first character of the string 001356 # X. 001357 # 001358 # EVIDENCE-OF: R-55469-62130 The char(X1,X2,...,XN) function returns a 001359 # string composed of characters having the unicode code point values of 001360 # integers X1 through XN, respectively. 001361 # 001362 do_execsql_test func-30.1 {SELECT unicode('$');} 36 001363 do_execsql_test func-30.2 [subst {SELECT unicode('\u00A2');}] 162 001364 do_execsql_test func-30.3 [subst {SELECT unicode('\u20AC');}] 8364 001365 do_execsql_test func-30.4 {SELECT char(36,162,8364);} [subst {$\u00A2\u20AC}] 001366 001367 for {set i 1} {$i<0xd800} {incr i 13} { 001368 do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i 001369 } 001370 for {set i 57344} {$i<=0xfffd} {incr i 17} { 001371 if {$i==0xfeff} continue 001372 do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i 001373 } 001374 for {set i 65536} {$i<=0x10ffff} {incr i 139} { 001375 do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i 001376 } 001377 001378 # Test char(). 001379 # 001380 do_execsql_test func-31.1 { 001381 SELECT char(), length(char()), typeof(char()) 001382 } {{} 0 text} 001383 finish_test