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