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