1b19a2bc6Sdrh# 2001 September 15 2ff6e9116Sdrh# 3b19a2bc6Sdrh# The author disclaims copyright to this source code. In place of 4b19a2bc6Sdrh# a legal notice, here is a blessing: 5ff6e9116Sdrh# 6b19a2bc6Sdrh# May you do good and not evil. 7b19a2bc6Sdrh# May you find forgiveness for yourself and forgive others. 8b19a2bc6Sdrh# May you share freely, never taking more than you give. 9ff6e9116Sdrh# 10ff6e9116Sdrh#*********************************************************************** 11ff6e9116Sdrh# This file implements regression tests for SQLite library. The 12ff6e9116Sdrh# focus of this file is testing built-in functions. 13ff6e9116Sdrh# 14ff6e9116Sdrh 15ff6e9116Sdrhset testdir [file dirname $argv0] 16ff6e9116Sdrhsource $testdir/tester.tcl 179ed04ebcSmistachkinset testprefix func 18ff6e9116Sdrh 19ff6e9116Sdrh# Create a table to work with. 20ff6e9116Sdrh# 21297ecf14Sdrhdo_test func-0.0 { 22ff6e9116Sdrh execsql {CREATE TABLE tbl1(t1 text)} 23ff6e9116Sdrh foreach word {this program is free software} { 24ff6e9116Sdrh execsql "INSERT INTO tbl1 VALUES('$word')" 25ff6e9116Sdrh } 26ff6e9116Sdrh execsql {SELECT t1 FROM tbl1 ORDER BY t1} 27ff6e9116Sdrh} {free is program software this} 28832508b7Sdrhdo_test func-0.1 { 29832508b7Sdrh execsql { 30832508b7Sdrh CREATE TABLE t2(a); 31832508b7Sdrh INSERT INTO t2 VALUES(1); 32832508b7Sdrh INSERT INTO t2 VALUES(NULL); 33832508b7Sdrh INSERT INTO t2 VALUES(345); 34832508b7Sdrh INSERT INTO t2 VALUES(NULL); 35832508b7Sdrh INSERT INTO t2 VALUES(67890); 36832508b7Sdrh SELECT * FROM t2; 37832508b7Sdrh } 38832508b7Sdrh} {1 {} 345 {} 67890} 39ff6e9116Sdrh 40ff6e9116Sdrh# Check out the length() function 41ff6e9116Sdrh# 42ff6e9116Sdrhdo_test func-1.0 { 43ff6e9116Sdrh execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 44ff6e9116Sdrh} {4 2 7 8 4} 45ff6e9116Sdrhdo_test func-1.1 { 46ff6e9116Sdrh set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg] 47ff6e9116Sdrh lappend r $msg 4889425d5eSdrh} {1 {wrong number of arguments to function length()}} 49ff6e9116Sdrhdo_test func-1.2 { 50ff6e9116Sdrh set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg] 51ff6e9116Sdrh lappend r $msg 5289425d5eSdrh} {1 {wrong number of arguments to function length()}} 53ff6e9116Sdrhdo_test func-1.3 { 54ff6e9116Sdrh execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1) 55ff6e9116Sdrh ORDER BY length(t1)} 56ff6e9116Sdrh} {2 1 4 2 7 1 8 1} 57832508b7Sdrhdo_test func-1.4 { 58bb113518Sdrh execsql {SELECT coalesce(length(a),-1) FROM t2} 59bb113518Sdrh} {1 -1 3 -1 5} 60ff6e9116Sdrh 61ff6e9116Sdrh# Check out the substr() function 62ff6e9116Sdrh# 63ff6e9116Sdrhdo_test func-2.0 { 64ff6e9116Sdrh execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 65ff6e9116Sdrh} {fr is pr so th} 66ff6e9116Sdrhdo_test func-2.1 { 67ff6e9116Sdrh execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1} 68ff6e9116Sdrh} {r s r o h} 69ff6e9116Sdrhdo_test func-2.2 { 70ff6e9116Sdrh execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1} 71ff6e9116Sdrh} {ee {} ogr ftw is} 72ff6e9116Sdrhdo_test func-2.3 { 73ff6e9116Sdrh execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 74ff6e9116Sdrh} {e s m e s} 75ff6e9116Sdrhdo_test func-2.4 { 76ff6e9116Sdrh execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1} 77ff6e9116Sdrh} {e s m e s} 78ff6e9116Sdrhdo_test func-2.5 { 79ff6e9116Sdrh execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1} 80ff6e9116Sdrh} {e i a r i} 81ff6e9116Sdrhdo_test func-2.6 { 82ff6e9116Sdrh execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1} 83ff6e9116Sdrh} {ee is am re is} 84ff6e9116Sdrhdo_test func-2.7 { 85ff6e9116Sdrh execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1} 86ff6e9116Sdrh} {fr {} gr wa th} 87ff6e9116Sdrhdo_test func-2.8 { 88ff6e9116Sdrh execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)} 89ff6e9116Sdrh} {this software free program is} 90832508b7Sdrhdo_test func-2.9 { 91832508b7Sdrh execsql {SELECT substr(a,1,1) FROM t2} 92832508b7Sdrh} {1 {} 3 {} 6} 93832508b7Sdrhdo_test func-2.10 { 94832508b7Sdrh execsql {SELECT substr(a,2,2) FROM t2} 95832508b7Sdrh} {{} {} 45 {} 78} 96ff6e9116Sdrh 97df014893Sdrh# Only do the following tests if TCL has UTF-8 capabilities 98297ecf14Sdrh# 99df014893Sdrhif {"\u1234"!="u1234"} { 100297ecf14Sdrh 101297ecf14Sdrh# Put some UTF-8 characters in the database 102297ecf14Sdrh# 103297ecf14Sdrhdo_test func-3.0 { 104297ecf14Sdrh execsql {DELETE FROM tbl1} 105297ecf14Sdrh foreach word "contains UTF-8 characters hi\u1234ho" { 106297ecf14Sdrh execsql "INSERT INTO tbl1 VALUES('$word')" 107297ecf14Sdrh } 108297ecf14Sdrh execsql {SELECT t1 FROM tbl1 ORDER BY t1} 109a9e99aeeSdrh} "UTF-8 characters contains hi\u1234ho" 110297ecf14Sdrhdo_test func-3.1 { 111297ecf14Sdrh execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 112a9e99aeeSdrh} {5 10 8 5} 113297ecf14Sdrhdo_test func-3.2 { 114297ecf14Sdrh execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 115a9e99aeeSdrh} {UT ch co hi} 116297ecf14Sdrhdo_test func-3.3 { 117297ecf14Sdrh execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1} 118a9e99aeeSdrh} "UTF cha con hi\u1234" 119297ecf14Sdrhdo_test func-3.4 { 120297ecf14Sdrh execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1} 121a9e99aeeSdrh} "TF ha on i\u1234" 122297ecf14Sdrhdo_test func-3.5 { 123297ecf14Sdrh execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1} 124a9e99aeeSdrh} "TF- har ont i\u1234h" 125297ecf14Sdrhdo_test func-3.6 { 126297ecf14Sdrh execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1} 127a9e99aeeSdrh} "F- ar nt \u1234h" 128297ecf14Sdrhdo_test func-3.7 { 129297ecf14Sdrh execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1} 130a9e99aeeSdrh} "-8 ra ta ho" 131297ecf14Sdrhdo_test func-3.8 { 132297ecf14Sdrh execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 133a9e99aeeSdrh} "8 s s o" 134297ecf14Sdrhdo_test func-3.9 { 135297ecf14Sdrh execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1} 136a9e99aeeSdrh} "F- er in \u1234h" 137297ecf14Sdrhdo_test func-3.10 { 138297ecf14Sdrh execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1} 139a9e99aeeSdrh} "TF- ter ain i\u1234h" 140832508b7Sdrhdo_test func-3.99 { 141832508b7Sdrh execsql {DELETE FROM tbl1} 142832508b7Sdrh foreach word {this program is free software} { 143832508b7Sdrh execsql "INSERT INTO tbl1 VALUES('$word')" 144832508b7Sdrh } 145832508b7Sdrh execsql {SELECT t1 FROM tbl1} 146832508b7Sdrh} {this program is free software} 147297ecf14Sdrh 148df014893Sdrh} ;# End \u1234!=u1234 149297ecf14Sdrh 150bf4133cbSdrh# Test the abs() and round() functions. 151bf4133cbSdrh# 152fbd60f82Sshaneifcapable !floatingpoint { 153fbd60f82Sshane do_test func-4.1 { 154fbd60f82Sshane execsql { 155fbd60f82Sshane CREATE TABLE t1(a,b,c); 156fbd60f82Sshane INSERT INTO t1 VALUES(1,2,3); 157fbd60f82Sshane INSERT INTO t1 VALUES(2,12345678901234,-1234567890); 158fbd60f82Sshane INSERT INTO t1 VALUES(3,-2,-5); 159fbd60f82Sshane } 160fbd60f82Sshane catchsql {SELECT abs(a,b) FROM t1} 161fbd60f82Sshane } {1 {wrong number of arguments to function abs()}} 162fbd60f82Sshane} 163fbd60f82Sshaneifcapable floatingpoint { 164bf4133cbSdrh do_test func-4.1 { 165bf4133cbSdrh execsql { 166bf4133cbSdrh CREATE TABLE t1(a,b,c); 167bf4133cbSdrh INSERT INTO t1 VALUES(1,2,3); 168bf4133cbSdrh INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890); 169bf4133cbSdrh INSERT INTO t1 VALUES(3,-2,-5); 170bf4133cbSdrh } 171bf4133cbSdrh catchsql {SELECT abs(a,b) FROM t1} 17289425d5eSdrh } {1 {wrong number of arguments to function abs()}} 173fbd60f82Sshane} 174bf4133cbSdrhdo_test func-4.2 { 175bf4133cbSdrh catchsql {SELECT abs() FROM t1} 17689425d5eSdrh} {1 {wrong number of arguments to function abs()}} 177fbd60f82Sshaneifcapable floatingpoint { 178bf4133cbSdrh do_test func-4.3 { 179bf4133cbSdrh catchsql {SELECT abs(b) FROM t1 ORDER BY a} 180bf4133cbSdrh } {0 {2 1.2345678901234 2}} 181bf4133cbSdrh do_test func-4.4 { 182bf4133cbSdrh catchsql {SELECT abs(c) FROM t1 ORDER BY a} 1833d1bfeaaSdanielk1977 } {0 {3 12345.6789 5}} 184fbd60f82Sshane} 185fbd60f82Sshaneifcapable !floatingpoint { 186fbd60f82Sshane if {[working_64bit_int]} { 187fbd60f82Sshane do_test func-4.3 { 188fbd60f82Sshane catchsql {SELECT abs(b) FROM t1 ORDER BY a} 189fbd60f82Sshane } {0 {2 12345678901234 2}} 190fbd60f82Sshane } 191fbd60f82Sshane do_test func-4.4 { 192fbd60f82Sshane catchsql {SELECT abs(c) FROM t1 ORDER BY a} 193fbd60f82Sshane } {0 {3 1234567890 5}} 194fbd60f82Sshane} 195832508b7Sdrhdo_test func-4.4.1 { 196832508b7Sdrh execsql {SELECT abs(a) FROM t2} 197832508b7Sdrh} {1 {} 345 {} 67890} 198832508b7Sdrhdo_test func-4.4.2 { 199832508b7Sdrh execsql {SELECT abs(t1) FROM tbl1} 20092febd92Sdrh} {0.0 0.0 0.0 0.0 0.0} 201bf4133cbSdrh 202fbd60f82Sshaneifcapable floatingpoint { 203bf4133cbSdrh do_test func-4.5 { 204bf4133cbSdrh catchsql {SELECT round(a,b,c) FROM t1} 20589425d5eSdrh } {1 {wrong number of arguments to function round()}} 206bf4133cbSdrh do_test func-4.6 { 2078aff1015Sdrh catchsql {SELECT round(b,2) FROM t1 ORDER BY b} 208d589a92aSdrh } {0 {-2.0 1.23 2.0}} 209bf4133cbSdrh do_test func-4.7 { 210bf4133cbSdrh catchsql {SELECT round(b,0) FROM t1 ORDER BY a} 211d589a92aSdrh } {0 {2.0 1.0 -2.0}} 212bf4133cbSdrh do_test func-4.8 { 213bf4133cbSdrh catchsql {SELECT round(c) FROM t1 ORDER BY a} 214d589a92aSdrh } {0 {3.0 -12346.0 -5.0}} 215bf4133cbSdrh do_test func-4.9 { 216bf4133cbSdrh catchsql {SELECT round(c,a) FROM t1 ORDER BY a} 217d589a92aSdrh } {0 {3.0 -12345.68 -5.0}} 218bf4133cbSdrh do_test func-4.10 { 21901a34661Sdrh catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a} 220d589a92aSdrh } {0 {x3.0y x-12345.68y x-5.0y}} 22101a34661Sdrh do_test func-4.11 { 222bf4133cbSdrh catchsql {SELECT round() FROM t1 ORDER BY a} 22389425d5eSdrh } {1 {wrong number of arguments to function round()}} 224832508b7Sdrh do_test func-4.12 { 225bb113518Sdrh execsql {SELECT coalesce(round(a,2),'nil') FROM t2} 226d589a92aSdrh } {1.0 nil 345.0 nil 67890.0} 227832508b7Sdrh do_test func-4.13 { 228832508b7Sdrh execsql {SELECT round(t1,2) FROM tbl1} 229d589a92aSdrh } {0.0 0.0 0.0 0.0 0.0} 230d589a92aSdrh do_test func-4.14 { 231d589a92aSdrh execsql {SELECT typeof(round(5.1,1));} 232d589a92aSdrh } {real} 233d589a92aSdrh do_test func-4.15 { 234d589a92aSdrh execsql {SELECT typeof(round(5.1));} 235d589a92aSdrh } {real} 236fbd60f82Sshane do_test func-4.16 { 237fbd60f82Sshane catchsql {SELECT round(b,2.0) FROM t1 ORDER BY b} 238fbd60f82Sshane } {0 {-2.0 1.23 2.0}} 2394a0b43caSshaneh # Verify some values reported on the mailing list. 2404a0b43caSshaneh # Some of these fail on MSVC builds with 64-bit 2414a0b43caSshaneh # long doubles, but not on GCC builds with 80-bit 2424a0b43caSshaneh # long doubles. 2434a0b43caSshaneh for {set i 1} {$i<999} {incr i} { 24435c1a793Sshaneh set x1 [expr 40222.5 + $i] 2454a0b43caSshaneh set x2 [expr 40223.0 + $i] 2464a0b43caSshaneh do_test func-4.17.$i { 2474a0b43caSshaneh execsql {SELECT round($x1);} 2484a0b43caSshaneh } $x2 2494a0b43caSshaneh } 25035c1a793Sshaneh for {set i 1} {$i<999} {incr i} { 25135c1a793Sshaneh set x1 [expr 40222.05 + $i] 25235c1a793Sshaneh set x2 [expr 40222.10 + $i] 25335c1a793Sshaneh do_test func-4.18.$i { 25435c1a793Sshaneh execsql {SELECT round($x1,1);} 25535c1a793Sshaneh } $x2 25635c1a793Sshaneh } 2574a0b43caSshaneh do_test func-4.20 { 2584a0b43caSshaneh execsql {SELECT round(40223.4999999999);} 2594a0b43caSshaneh } {40223.0} 2604a0b43caSshaneh do_test func-4.21 { 2614a0b43caSshaneh execsql {SELECT round(40224.4999999999);} 2624a0b43caSshaneh } {40224.0} 2634a0b43caSshaneh do_test func-4.22 { 2644a0b43caSshaneh execsql {SELECT round(40225.4999999999);} 2654a0b43caSshaneh } {40225.0} 2664a0b43caSshaneh for {set i 1} {$i<10} {incr i} { 2674a0b43caSshaneh do_test func-4.23.$i { 2684a0b43caSshaneh execsql {SELECT round(40223.4999999999,$i);} 2694a0b43caSshaneh } {40223.5} 2704a0b43caSshaneh do_test func-4.24.$i { 2714a0b43caSshaneh execsql {SELECT round(40224.4999999999,$i);} 2724a0b43caSshaneh } {40224.5} 2734a0b43caSshaneh do_test func-4.25.$i { 2744a0b43caSshaneh execsql {SELECT round(40225.4999999999,$i);} 2754a0b43caSshaneh } {40225.5} 2764a0b43caSshaneh } 2774a0b43caSshaneh for {set i 10} {$i<32} {incr i} { 2784a0b43caSshaneh do_test func-4.26.$i { 2794a0b43caSshaneh execsql {SELECT round(40223.4999999999,$i);} 2804a0b43caSshaneh } {40223.4999999999} 2814a0b43caSshaneh do_test func-4.27.$i { 2824a0b43caSshaneh execsql {SELECT round(40224.4999999999,$i);} 2834a0b43caSshaneh } {40224.4999999999} 2844a0b43caSshaneh do_test func-4.28.$i { 2854a0b43caSshaneh execsql {SELECT round(40225.4999999999,$i);} 2864a0b43caSshaneh } {40225.4999999999} 2874a0b43caSshaneh } 2884a0b43caSshaneh do_test func-4.29 { 2894a0b43caSshaneh execsql {SELECT round(1234567890.5);} 2904a0b43caSshaneh } {1234567891.0} 2914a0b43caSshaneh do_test func-4.30 { 2924a0b43caSshaneh execsql {SELECT round(12345678901.5);} 2934a0b43caSshaneh } {12345678902.0} 2944a0b43caSshaneh do_test func-4.31 { 2954a0b43caSshaneh execsql {SELECT round(123456789012.5);} 2964a0b43caSshaneh } {123456789013.0} 2974a0b43caSshaneh do_test func-4.32 { 2984a0b43caSshaneh execsql {SELECT round(1234567890123.5);} 2994a0b43caSshaneh } {1234567890124.0} 3004a0b43caSshaneh do_test func-4.33 { 3014a0b43caSshaneh execsql {SELECT round(12345678901234.5);} 3024a0b43caSshaneh } {12345678901235.0} 3034a0b43caSshaneh do_test func-4.34 { 3044a0b43caSshaneh execsql {SELECT round(1234567890123.35,1);} 3054a0b43caSshaneh } {1234567890123.4} 3064a0b43caSshaneh do_test func-4.35 { 3074a0b43caSshaneh execsql {SELECT round(1234567890123.445,2);} 3084a0b43caSshaneh } {1234567890123.45} 3094a0b43caSshaneh do_test func-4.36 { 3104a0b43caSshaneh execsql {SELECT round(99999999999994.5);} 3114a0b43caSshaneh } {99999999999995.0} 3124a0b43caSshaneh do_test func-4.37 { 3134a0b43caSshaneh execsql {SELECT round(9999999999999.55,1);} 3144a0b43caSshaneh } {9999999999999.6} 3154a0b43caSshaneh do_test func-4.38 { 3164aaf1552Sdrh execsql {SELECT round(9999999999999.556,2);} 3174a0b43caSshaneh } {9999999999999.56} 3185710f1adSdrh do_test func-4.39 { 3195710f1adSdrh string tolower [db eval {SELECT round(1e500), round(-1e500);}] 3205710f1adSdrh } {inf -inf} 321fbd60f82Sshane} 322832508b7Sdrh 323832508b7Sdrh# Test the upper() and lower() functions 324832508b7Sdrh# 325832508b7Sdrhdo_test func-5.1 { 326832508b7Sdrh execsql {SELECT upper(t1) FROM tbl1} 327832508b7Sdrh} {THIS PROGRAM IS FREE SOFTWARE} 328832508b7Sdrhdo_test func-5.2 { 329832508b7Sdrh execsql {SELECT lower(upper(t1)) FROM tbl1} 330832508b7Sdrh} {this program is free software} 331832508b7Sdrhdo_test func-5.3 { 332832508b7Sdrh execsql {SELECT upper(a), lower(a) FROM t2} 333832508b7Sdrh} {1 1 {} {} 345 345 {} {} 67890 67890} 3347de68a09Sdanielk1977ifcapable !icu { 335832508b7Sdrh do_test func-5.4 { 336832508b7Sdrh catchsql {SELECT upper(a,5) FROM t2} 337832508b7Sdrh } {1 {wrong number of arguments to function upper()}} 3387de68a09Sdanielk1977} 339832508b7Sdrhdo_test func-5.5 { 340832508b7Sdrh catchsql {SELECT upper(*) FROM t2} 341832508b7Sdrh} {1 {wrong number of arguments to function upper()}} 342832508b7Sdrh 343a9f9d1c0Sdrh# Test the coalesce() and nullif() functions 344832508b7Sdrh# 345832508b7Sdrhdo_test func-6.1 { 346832508b7Sdrh execsql {SELECT coalesce(a,'xyz') FROM t2} 347832508b7Sdrh} {1 xyz 345 xyz 67890} 348832508b7Sdrhdo_test func-6.2 { 349832508b7Sdrh execsql {SELECT coalesce(upper(a),'nil') FROM t2} 350832508b7Sdrh} {1 nil 345 nil 67890} 351a9f9d1c0Sdrhdo_test func-6.3 { 352a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,1),'nil')} 353a9f9d1c0Sdrh} {nil} 354a9f9d1c0Sdrhdo_test func-6.4 { 355a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,2),'nil')} 356a9f9d1c0Sdrh} {1} 357a9f9d1c0Sdrhdo_test func-6.5 { 358a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,NULL),'nil')} 359a9f9d1c0Sdrh} {1} 360a9f9d1c0Sdrh 361832508b7Sdrh 3626ed41ad7Sdrh# Test the last_insert_rowid() function 3636ed41ad7Sdrh# 3646ed41ad7Sdrhdo_test func-7.1 { 3656ed41ad7Sdrh execsql {SELECT last_insert_rowid()} 3666ed41ad7Sdrh} [db last_insert_rowid] 3676ed41ad7Sdrh 368739105c7Sdrh# Tests for aggregate functions and how they handle NULLs. 369739105c7Sdrh# 370fbd60f82Sshaneifcapable floatingpoint { 371739105c7Sdrh do_test func-8.1 { 3724489f9bdSdanielk1977 ifcapable explain { 373c5cdca61Sdrh execsql {EXPLAIN SELECT sum(a) FROM t2;} 3744489f9bdSdanielk1977 } 375739105c7Sdrh execsql { 376739105c7Sdrh SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2; 377739105c7Sdrh } 3783d1d95e6Sdrh } {68236 3 22745.33 1 67890 5} 379fbd60f82Sshane} 380fbd60f82Sshaneifcapable !floatingpoint { 381fbd60f82Sshane do_test func-8.1 { 382fbd60f82Sshane ifcapable explain { 383fbd60f82Sshane execsql {EXPLAIN SELECT sum(a) FROM t2;} 384fbd60f82Sshane } 385fbd60f82Sshane execsql { 386fbd60f82Sshane SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2; 387fbd60f82Sshane } 388fbd60f82Sshane } {68236 3 22745.0 1 67890 5} 389fbd60f82Sshane} 390a9f9d1c0Sdrhdo_test func-8.2 { 391a9f9d1c0Sdrh execsql { 392a9f9d1c0Sdrh SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; 393a9f9d1c0Sdrh } 394a9f9d1c0Sdrh} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 39553c0f748Sdanielk1977 39653c0f748Sdanielk1977ifcapable tempdb { 397a9f9d1c0Sdrh do_test func-8.3 { 398a9f9d1c0Sdrh execsql { 399a9f9d1c0Sdrh CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 400a9f9d1c0Sdrh SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 401a9f9d1c0Sdrh } 4029eb516c0Sdrh } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 40353c0f748Sdanielk1977} else { 40453c0f748Sdanielk1977 do_test func-8.3 { 40553c0f748Sdanielk1977 execsql { 40653c0f748Sdanielk1977 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 40753c0f748Sdanielk1977 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 40853c0f748Sdanielk1977 } 40953c0f748Sdanielk1977 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 41053c0f748Sdanielk1977} 4113aeab9e4Sdanielk1977do_test func-8.4 { 4123aeab9e4Sdanielk1977 execsql { 4133aeab9e4Sdanielk1977 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 4143aeab9e4Sdanielk1977 } 4153aeab9e4Sdanielk1977} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 416de3e41e3Sdanielk1977ifcapable compound { 41785e9e22bSdrh do_test func-8.5 { 41885e9e22bSdrh execsql { 41985e9e22bSdrh SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x 42085e9e22bSdrh UNION ALL SELECT -9223372036854775807) 42185e9e22bSdrh } 42285e9e22bSdrh } {0} 42385e9e22bSdrh do_test func-8.6 { 42485e9e22bSdrh execsql { 42506a0a81cSdrh SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x 42606a0a81cSdrh UNION ALL SELECT -9223372036854775807) 42706a0a81cSdrh } 42806a0a81cSdrh } {integer} 42906a0a81cSdrh do_test func-8.7 { 43006a0a81cSdrh execsql { 43101859b0bSdrh SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x 43285e9e22bSdrh UNION ALL SELECT -9223372036854775807) 43385e9e22bSdrh } 43401859b0bSdrh } {real} 435fbd60f82Sshaneifcapable floatingpoint { 43606a0a81cSdrh do_test func-8.8 { 43701859b0bSdrh execsql { 43806a0a81cSdrh SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x 43901859b0bSdrh UNION ALL SELECT -9223372036850000000) 44001859b0bSdrh } 44106a0a81cSdrh } {1} 442de3e41e3Sdanielk1977} 443fbd60f82Sshaneifcapable !floatingpoint { 444fbd60f82Sshane do_test func-8.8 { 445fbd60f82Sshane execsql { 446fbd60f82Sshane SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x 447fbd60f82Sshane UNION ALL SELECT -9223372036850000000) 448fbd60f82Sshane } 449fbd60f82Sshane } {1} 450fbd60f82Sshane} 451fbd60f82Sshane} 452739105c7Sdrh 453a9f9d1c0Sdrh# How do you test the random() function in a meaningful, deterministic way? 454a9f9d1c0Sdrh# 455a9f9d1c0Sdrhdo_test func-9.1 { 456a9f9d1c0Sdrh execsql { 457a9f9d1c0Sdrh SELECT random() is not null; 458a9f9d1c0Sdrh } 459a9f9d1c0Sdrh} {1} 46063cf66f0Sdrhdo_test func-9.2 { 46163cf66f0Sdrh execsql { 46263cf66f0Sdrh SELECT typeof(random()); 46363cf66f0Sdrh } 46463cf66f0Sdrh} {integer} 46563cf66f0Sdrhdo_test func-9.3 { 46663cf66f0Sdrh execsql { 467137c728fSdrh SELECT randomblob(32) is not null; 46863cf66f0Sdrh } 46963cf66f0Sdrh} {1} 47063cf66f0Sdrhdo_test func-9.4 { 47163cf66f0Sdrh execsql { 472137c728fSdrh SELECT typeof(randomblob(32)); 47363cf66f0Sdrh } 474137c728fSdrh} {blob} 47563cf66f0Sdrhdo_test func-9.5 { 47663cf66f0Sdrh execsql { 477137c728fSdrh SELECT length(randomblob(32)), length(randomblob(-5)), 478137c728fSdrh length(randomblob(2000)) 47963cf66f0Sdrh } 480137c728fSdrh} {32 1 2000} 48163cf66f0Sdrh 482137c728fSdrh# The "hex()" function was added in order to be able to render blobs 483137c728fSdrh# generated by randomblob(). So this seems like a good place to test 484137c728fSdrh# hex(). 485137c728fSdrh# 4864152e677Sdanielk1977ifcapable bloblit { 487137c728fSdrh do_test func-9.10 { 488137c728fSdrh execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')} 489137c728fSdrh } {00112233445566778899AABBCCDDEEFF} 4904152e677Sdanielk1977} 491056c8f78Sdrhset encoding [db one {PRAGMA encoding}] 492056c8f78Sdrhif {$encoding=="UTF-16le"} { 493056c8f78Sdrh do_test func-9.11-utf16le { 4941eb2538aSdrh execsql {SELECT hex(replace('abcdefg','ef','12'))} 495056c8f78Sdrh } {6100620063006400310032006700} 496056c8f78Sdrh do_test func-9.12-utf16le { 497709cff33Sdrh execsql {SELECT hex(replace('abcdefg','','12'))} 498a605fe8dSdrh } {6100620063006400650066006700} 499056c8f78Sdrh do_test func-9.13-utf16le { 500056c8f78Sdrh execsql {SELECT hex(replace('aabcdefg','a','aaa'))} 501056c8f78Sdrh } {610061006100610061006100620063006400650066006700} 502056c8f78Sdrh} elseif {$encoding=="UTF-8"} { 503056c8f78Sdrh do_test func-9.11-utf8 { 504056c8f78Sdrh execsql {SELECT hex(replace('abcdefg','ef','12'))} 505056c8f78Sdrh } {61626364313267} 506056c8f78Sdrh do_test func-9.12-utf8 { 507056c8f78Sdrh execsql {SELECT hex(replace('abcdefg','','12'))} 508a605fe8dSdrh } {61626364656667} 509056c8f78Sdrh do_test func-9.13-utf8 { 510709cff33Sdrh execsql {SELECT hex(replace('aabcdefg','a','aaa'))} 511709cff33Sdrh } {616161616161626364656667} 512056c8f78Sdrh} 513f3139520Sdrhdo_execsql_test func-9.14 { 514f3139520Sdrh WITH RECURSIVE c(x) AS ( 515f3139520Sdrh VALUES(1) 516f3139520Sdrh UNION ALL 517f3139520Sdrh SELECT x+1 FROM c WHERE x<1040 518f3139520Sdrh ) 519f3139520Sdrh SELECT 520f3139520Sdrh count(*), 521f3139520Sdrh sum(length(replace(printf('abc%.*cxyz',x,'m'),'m','nnnn'))-(6+x*4)) 522f3139520Sdrh FROM c; 523f3139520Sdrh} {1040 0} 524bf4133cbSdrh 5256cbe1f1bSdrh# Use the "sqlite_register_test_function" TCL command which is part of 5266cbe1f1bSdrh# the text fixture in order to verify correct operation of some of 5276cbe1f1bSdrh# the user-defined SQL function APIs that are not used by the built-in 5286cbe1f1bSdrh# functions. 5296cbe1f1bSdrh# 530dddca286Sdrhset ::DB [sqlite3_connection_pointer db] 5316cbe1f1bSdrhsqlite_register_test_function $::DB testfunc 5326cbe1f1bSdrhdo_test func-10.1 { 5336cbe1f1bSdrh catchsql { 5346cbe1f1bSdrh SELECT testfunc(NULL,NULL); 5356cbe1f1bSdrh } 5366d88bad4Sdanielk1977} {1 {first argument should be one of: int int64 string double null value}} 5376cbe1f1bSdrhdo_test func-10.2 { 5386cbe1f1bSdrh execsql { 5396cbe1f1bSdrh SELECT testfunc( 5406cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5416cbe1f1bSdrh 'int', 1234 5426cbe1f1bSdrh ); 5436cbe1f1bSdrh } 5446cbe1f1bSdrh} {1234} 5456cbe1f1bSdrhdo_test func-10.3 { 5466cbe1f1bSdrh execsql { 5476cbe1f1bSdrh SELECT testfunc( 5486cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5496cbe1f1bSdrh 'string', NULL 5506cbe1f1bSdrh ); 5516cbe1f1bSdrh } 5526cbe1f1bSdrh} {{}} 553fbd60f82Sshane 554fbd60f82Sshaneifcapable floatingpoint { 5556cbe1f1bSdrh do_test func-10.4 { 5566cbe1f1bSdrh execsql { 5576cbe1f1bSdrh SELECT testfunc( 5586cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5596cbe1f1bSdrh 'double', 1.234 5606cbe1f1bSdrh ); 5616cbe1f1bSdrh } 5626cbe1f1bSdrh } {1.234} 5636cbe1f1bSdrh do_test func-10.5 { 5646cbe1f1bSdrh execsql { 5656cbe1f1bSdrh SELECT testfunc( 5666cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5676cbe1f1bSdrh 'int', 1234, 5686cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5696cbe1f1bSdrh 'string', NULL, 5706cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5716cbe1f1bSdrh 'double', 1.234, 5726cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5736cbe1f1bSdrh 'int', 1234, 5746cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5756cbe1f1bSdrh 'string', NULL, 5766cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 5776cbe1f1bSdrh 'double', 1.234 5786cbe1f1bSdrh ); 5796cbe1f1bSdrh } 5806cbe1f1bSdrh } {1.234} 581fbd60f82Sshane} 5826cbe1f1bSdrh 583647cb0e1Sdrh# Test the built-in sqlite_version(*) SQL function. 584647cb0e1Sdrh# 585647cb0e1Sdrhdo_test func-11.1 { 586647cb0e1Sdrh execsql { 587647cb0e1Sdrh SELECT sqlite_version(*); 588647cb0e1Sdrh } 589ef4ac8f9Sdrh} [sqlite3 -version] 590647cb0e1Sdrh 591ef4ac8f9Sdrh# Test that destructors passed to sqlite3 by calls to sqlite3_result_text() 5923f6b0874Sdanielk1977# etc. are called. These tests use two special user-defined functions 5933f6b0874Sdanielk1977# (implemented in func.c) only available in test builds. 5943f6b0874Sdanielk1977# 5953f6b0874Sdanielk1977# Function test_destructor() takes one argument and returns a copy of the 5963f6b0874Sdanielk1977# text form of that argument. A destructor is associated with the return 5973f6b0874Sdanielk1977# value. Function test_destructor_count() returns the number of outstanding 5983f6b0874Sdanielk1977# destructor calls for values returned by test_destructor(). 5993f6b0874Sdanielk1977# 600da84ca8dSdrhif {[db eval {PRAGMA encoding}]=="UTF-8"} { 601da84ca8dSdrh do_test func-12.1-utf8 { 602d8123366Sdanielk1977 execsql { 603d8123366Sdanielk1977 SELECT test_destructor('hello world'), test_destructor_count(); 604d8123366Sdanielk1977 } 605d8123366Sdanielk1977 } {{hello world} 1} 606da84ca8dSdrh} else { 6072a5fc4d6Sshane ifcapable {utf16} { 608da84ca8dSdrh do_test func-12.1-utf16 { 609da84ca8dSdrh execsql { 610da84ca8dSdrh SELECT test_destructor16('hello world'), test_destructor_count(); 611da84ca8dSdrh } 612da84ca8dSdrh } {{hello world} 1} 613da84ca8dSdrh } 6142a5fc4d6Sshane} 615d8123366Sdanielk1977do_test func-12.2 { 616d8123366Sdanielk1977 execsql { 617d8123366Sdanielk1977 SELECT test_destructor_count(); 618d8123366Sdanielk1977 } 619d8123366Sdanielk1977} {0} 620d8123366Sdanielk1977do_test func-12.3 { 621d8123366Sdanielk1977 execsql { 6222dcef11bSdrh SELECT test_destructor('hello')||' world' 623d8123366Sdanielk1977 } 6242dcef11bSdrh} {{hello world}} 625d8123366Sdanielk1977do_test func-12.4 { 626d8123366Sdanielk1977 execsql { 627d8123366Sdanielk1977 SELECT test_destructor_count(); 628d8123366Sdanielk1977 } 629d8123366Sdanielk1977} {0} 630d8123366Sdanielk1977do_test func-12.5 { 631d8123366Sdanielk1977 execsql { 632d8123366Sdanielk1977 CREATE TABLE t4(x); 633d8123366Sdanielk1977 INSERT INTO t4 VALUES(test_destructor('hello')); 634d8123366Sdanielk1977 INSERT INTO t4 VALUES(test_destructor('world')); 635d8123366Sdanielk1977 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4; 636d8123366Sdanielk1977 } 637d8123366Sdanielk1977} {hello world} 638d8123366Sdanielk1977do_test func-12.6 { 639d8123366Sdanielk1977 execsql { 640d8123366Sdanielk1977 SELECT test_destructor_count(); 641d8123366Sdanielk1977 } 642d8123366Sdanielk1977} {0} 6433f6b0874Sdanielk1977do_test func-12.7 { 6443f6b0874Sdanielk1977 execsql { 6453f6b0874Sdanielk1977 DROP TABLE t4; 6463f6b0874Sdanielk1977 } 6473f6b0874Sdanielk1977} {} 6483f6b0874Sdanielk1977 649a4e5d58fSdrh 6503f6b0874Sdanielk1977# Test that the auxdata API for scalar functions works. This test uses 6513f6b0874Sdanielk1977# a special user-defined function only available in test builds, 6523f6b0874Sdanielk1977# test_auxdata(). Function test_auxdata() takes any number of arguments. 6533f6b0874Sdanielk1977do_test func-13.1 { 6543f6b0874Sdanielk1977 execsql { 6553f6b0874Sdanielk1977 SELECT test_auxdata('hello world'); 6563f6b0874Sdanielk1977 } 6573f6b0874Sdanielk1977} {0} 658ece80f1eSdanielk1977 6593f6b0874Sdanielk1977do_test func-13.2 { 6603f6b0874Sdanielk1977 execsql { 6613f6b0874Sdanielk1977 CREATE TABLE t4(a, b); 6623f6b0874Sdanielk1977 INSERT INTO t4 VALUES('abc', 'def'); 6633f6b0874Sdanielk1977 INSERT INTO t4 VALUES('ghi', 'jkl'); 6643f6b0874Sdanielk1977 } 6653f6b0874Sdanielk1977} {} 6663f6b0874Sdanielk1977do_test func-13.3 { 6673f6b0874Sdanielk1977 execsql { 6683f6b0874Sdanielk1977 SELECT test_auxdata('hello world') FROM t4; 6693f6b0874Sdanielk1977 } 6703f6b0874Sdanielk1977} {0 1} 6713f6b0874Sdanielk1977do_test func-13.4 { 6723f6b0874Sdanielk1977 execsql { 6733f6b0874Sdanielk1977 SELECT test_auxdata('hello world', 123) FROM t4; 6743f6b0874Sdanielk1977 } 6753f6b0874Sdanielk1977} {{0 0} {1 1}} 6763f6b0874Sdanielk1977do_test func-13.5 { 6773f6b0874Sdanielk1977 execsql { 6783f6b0874Sdanielk1977 SELECT test_auxdata('hello world', a) FROM t4; 6793f6b0874Sdanielk1977 } 6803f6b0874Sdanielk1977} {{0 0} {1 0}} 6813f6b0874Sdanielk1977do_test func-13.6 { 6823f6b0874Sdanielk1977 execsql { 6833f6b0874Sdanielk1977 SELECT test_auxdata('hello'||'world', a) FROM t4; 6843f6b0874Sdanielk1977 } 6853f6b0874Sdanielk1977} {{0 0} {1 0}} 6863f6b0874Sdanielk1977 6873f6b0874Sdanielk1977# Test that auxilary data is preserved between calls for SQL variables. 6883f6b0874Sdanielk1977do_test func-13.7 { 689dddca286Sdrh set DB [sqlite3_connection_pointer db] 6903f6b0874Sdanielk1977 set sql "SELECT test_auxdata( ? , a ) FROM t4;" 6913f6b0874Sdanielk1977 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 69210dfbbb5Sdrh sqlite3_bind_text $STMT 1 hello\000 -1 6933f6b0874Sdanielk1977 set res [list] 6943f6b0874Sdanielk1977 while { "SQLITE_ROW"==[sqlite3_step $STMT] } { 6953f6b0874Sdanielk1977 lappend res [sqlite3_column_text $STMT 0] 6963f6b0874Sdanielk1977 } 6973f6b0874Sdanielk1977 lappend res [sqlite3_finalize $STMT] 6983f6b0874Sdanielk1977} {{0 0} {1 0} SQLITE_OK} 699d8123366Sdanielk1977 7000c547799Sdan# Test that auxiliary data is discarded when a statement is reset. 7010c547799Sdando_execsql_test 13.8.1 { 7020c547799Sdan SELECT test_auxdata('constant') FROM t4; 7030c547799Sdan} {0 1} 7040c547799Sdando_execsql_test 13.8.2 { 7050c547799Sdan SELECT test_auxdata('constant') FROM t4; 7060c547799Sdan} {0 1} 7070c547799Sdandb cache flush 7080c547799Sdando_execsql_test 13.8.3 { 7090c547799Sdan SELECT test_auxdata('constant') FROM t4; 7100c547799Sdan} {0 1} 7110c547799Sdanset V "one" 7120c547799Sdando_execsql_test 13.8.4 { 7130c547799Sdan SELECT test_auxdata($V), $V FROM t4; 7140c547799Sdan} {0 one 1 one} 7150c547799Sdanset V "two" 7160c547799Sdando_execsql_test 13.8.5 { 7170c547799Sdan SELECT test_auxdata($V), $V FROM t4; 7180c547799Sdan} {0 two 1 two} 7190c547799Sdandb cache flush 7200c547799Sdanset V "three" 7219ed04ebcSmistachkindo_execsql_test 13.8.6 { 7220c547799Sdan SELECT test_auxdata($V), $V FROM t4; 7230c547799Sdan} {0 three 1 three} 7240c547799Sdan 7250c547799Sdan 726312d6b36Sdanielk1977# Make sure that a function with a very long name is rejected 727312d6b36Sdanielk1977do_test func-14.1 { 728312d6b36Sdanielk1977 catch { 729312d6b36Sdanielk1977 db function [string repeat X 254] {return "hello"} 730312d6b36Sdanielk1977 } 731312d6b36Sdanielk1977} {0} 732312d6b36Sdanielk1977do_test func-14.2 { 733312d6b36Sdanielk1977 catch { 734312d6b36Sdanielk1977 db function [string repeat X 256] {return "hello"} 735312d6b36Sdanielk1977 } 736312d6b36Sdanielk1977} {1} 737312d6b36Sdanielk1977 73801427a62Sdanielk1977do_test func-15.1 { 73900e087b2Sdrh catchsql {select test_error(NULL)} 74090669c1dSdrh} {1 {}} 74100e087b2Sdrhdo_test func-15.2 { 74200e087b2Sdrh catchsql {select test_error('this is the error message')} 74300e087b2Sdrh} {1 {this is the error message}} 74400e087b2Sdrhdo_test func-15.3 { 74500e087b2Sdrh catchsql {select test_error('this is the error message',12)} 74600e087b2Sdrh} {1 {this is the error message}} 74700e087b2Sdrhdo_test func-15.4 { 74800e087b2Sdrh db errorcode 74900e087b2Sdrh} {12} 75001427a62Sdanielk1977 751576ec6b3Sdanielk1977# Test the quote function for BLOB and NULL values. 752576ec6b3Sdanielk1977do_test func-16.1 { 753576ec6b3Sdanielk1977 execsql { 754576ec6b3Sdanielk1977 CREATE TABLE tbl2(a, b); 755576ec6b3Sdanielk1977 } 756576ec6b3Sdanielk1977 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL] 757576ec6b3Sdanielk1977 sqlite3_bind_blob $::STMT 1 abc 3 758576ec6b3Sdanielk1977 sqlite3_step $::STMT 759576ec6b3Sdanielk1977 sqlite3_finalize $::STMT 760576ec6b3Sdanielk1977 execsql { 761576ec6b3Sdanielk1977 SELECT quote(a), quote(b) FROM tbl2; 762576ec6b3Sdanielk1977 } 763576ec6b3Sdanielk1977} {X'616263' NULL} 764576ec6b3Sdanielk1977 7652501eb1dSdrh# Correctly handle function error messages that include %. Ticket #1354 7662501eb1dSdrh# 7672501eb1dSdrhdo_test func-17.1 { 7682501eb1dSdrh proc testfunc1 args {error "Error %d with %s percents %p"} 7692501eb1dSdrh db function testfunc1 ::testfunc1 7702501eb1dSdrh catchsql { 7712501eb1dSdrh SELECT testfunc1(1,2,3); 7722501eb1dSdrh } 7732501eb1dSdrh} {1 {Error %d with %s percents %p}} 7742501eb1dSdrh 7753d1d95e6Sdrh# The SUM function should return integer results when all inputs are integer. 7763d1d95e6Sdrh# 7773d1d95e6Sdrhdo_test func-18.1 { 7783d1d95e6Sdrh execsql { 7793d1d95e6Sdrh CREATE TABLE t5(x); 7803d1d95e6Sdrh INSERT INTO t5 VALUES(1); 7813d1d95e6Sdrh INSERT INTO t5 VALUES(-99); 7823d1d95e6Sdrh INSERT INTO t5 VALUES(10000); 7833d1d95e6Sdrh SELECT sum(x) FROM t5; 7843d1d95e6Sdrh } 7853d1d95e6Sdrh} {9902} 786fbd60f82Sshaneifcapable floatingpoint { 7873d1d95e6Sdrh do_test func-18.2 { 7883d1d95e6Sdrh execsql { 7893d1d95e6Sdrh INSERT INTO t5 VALUES(0.0); 7903d1d95e6Sdrh SELECT sum(x) FROM t5; 7913d1d95e6Sdrh } 7928a51256cSdrh } {9902.0} 793fbd60f82Sshane} 794576ec6b3Sdanielk1977 795c2bd913aSdrh# The sum of nothing is NULL. But the sum of all NULLs is NULL. 7963f219f46Sdrh# 79776c730c1Sdrh# The TOTAL of nothing is 0.0. 79876c730c1Sdrh# 7993f219f46Sdrhdo_test func-18.3 { 8003f219f46Sdrh execsql { 8013f219f46Sdrh DELETE FROM t5; 80276c730c1Sdrh SELECT sum(x), total(x) FROM t5; 8033f219f46Sdrh } 80476c730c1Sdrh} {{} 0.0} 8053f219f46Sdrhdo_test func-18.4 { 8063f219f46Sdrh execsql { 8073f219f46Sdrh INSERT INTO t5 VALUES(NULL); 80876c730c1Sdrh SELECT sum(x), total(x) FROM t5 8093f219f46Sdrh } 81076c730c1Sdrh} {{} 0.0} 8113f219f46Sdrhdo_test func-18.5 { 8123f219f46Sdrh execsql { 8133f219f46Sdrh INSERT INTO t5 VALUES(NULL); 81476c730c1Sdrh SELECT sum(x), total(x) FROM t5 8153f219f46Sdrh } 81676c730c1Sdrh} {{} 0.0} 8173f219f46Sdrhdo_test func-18.6 { 8183f219f46Sdrh execsql { 8193f219f46Sdrh INSERT INTO t5 VALUES(123); 82076c730c1Sdrh SELECT sum(x), total(x) FROM t5 8213f219f46Sdrh } 82276c730c1Sdrh} {123 123.0} 8235708d2deSdrh 8248c08e861Sdrh# Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes 8258c08e861Sdrh# an error. The non-standard TOTAL() function continues to give a helpful 8268c08e861Sdrh# result. 827fc6ad39cSdrh# 828fc6ad39cSdrhdo_test func-18.10 { 829fc6ad39cSdrh execsql { 830fc6ad39cSdrh CREATE TABLE t6(x INTEGER); 831fc6ad39cSdrh INSERT INTO t6 VALUES(1); 832fc6ad39cSdrh INSERT INTO t6 VALUES(1<<62); 833fc6ad39cSdrh SELECT sum(x) - ((1<<62)+1) from t6; 834fc6ad39cSdrh } 835fc6ad39cSdrh} 0 83676c730c1Sdrhdo_test func-18.11 { 83776c730c1Sdrh execsql { 83876c730c1Sdrh SELECT typeof(sum(x)) FROM t6 83976c730c1Sdrh } 84076c730c1Sdrh} integer 841fbd60f82Sshaneifcapable floatingpoint { 84276c730c1Sdrh do_test func-18.12 { 8438c08e861Sdrh catchsql { 84476c730c1Sdrh INSERT INTO t6 VALUES(1<<62); 84576c730c1Sdrh SELECT sum(x) - ((1<<62)*2.0+1) from t6; 84676c730c1Sdrh } 8478c08e861Sdrh } {1 {integer overflow}} 84876c730c1Sdrh do_test func-18.13 { 84976c730c1Sdrh execsql { 85076c730c1Sdrh SELECT total(x) - ((1<<62)*2.0+1) FROM t6 85176c730c1Sdrh } 85276c730c1Sdrh } 0.0 853fbd60f82Sshane} 854fbd60f82Sshaneifcapable !floatingpoint { 855fbd60f82Sshane do_test func-18.12 { 856fbd60f82Sshane catchsql { 857fbd60f82Sshane INSERT INTO t6 VALUES(1<<62); 858fbd60f82Sshane SELECT sum(x) - ((1<<62)*2+1) from t6; 859fbd60f82Sshane } 860fbd60f82Sshane } {1 {integer overflow}} 861fbd60f82Sshane do_test func-18.13 { 862fbd60f82Sshane execsql { 863fbd60f82Sshane SELECT total(x) - ((1<<62)*2+1) FROM t6 864fbd60f82Sshane } 865fbd60f82Sshane } 0.0 866fbd60f82Sshane} 867fbd60f82Sshaneif {[working_64bit_int]} { 8688c08e861Sdrh do_test func-18.14 { 8698c08e861Sdrh execsql { 8708c08e861Sdrh SELECT sum(-9223372036854775805); 8718c08e861Sdrh } 8728c08e861Sdrh } -9223372036854775805 873fbd60f82Sshane} 8744b2688abSdanielk1977ifcapable compound&&subquery { 8754b2688abSdanielk1977 8768c08e861Sdrhdo_test func-18.15 { 8778c08e861Sdrh catchsql { 8788c08e861Sdrh SELECT sum(x) FROM 8798c08e861Sdrh (SELECT 9223372036854775807 AS x UNION ALL 8808c08e861Sdrh SELECT 10 AS x); 8818c08e861Sdrh } 8828c08e861Sdrh} {1 {integer overflow}} 883fbd60f82Sshaneif {[working_64bit_int]} { 8848c08e861Sdrh do_test func-18.16 { 8858c08e861Sdrh catchsql { 8868c08e861Sdrh SELECT sum(x) FROM 8878c08e861Sdrh (SELECT 9223372036854775807 AS x UNION ALL 8888c08e861Sdrh SELECT -10 AS x); 8898c08e861Sdrh } 8908c08e861Sdrh } {0 9223372036854775797} 8918c08e861Sdrh do_test func-18.17 { 8928c08e861Sdrh catchsql { 8938c08e861Sdrh SELECT sum(x) FROM 8948c08e861Sdrh (SELECT -9223372036854775807 AS x UNION ALL 8958c08e861Sdrh SELECT 10 AS x); 8968c08e861Sdrh } 8978c08e861Sdrh } {0 -9223372036854775797} 898fbd60f82Sshane} 8998c08e861Sdrhdo_test func-18.18 { 9008c08e861Sdrh catchsql { 9018c08e861Sdrh SELECT sum(x) FROM 9028c08e861Sdrh (SELECT -9223372036854775807 AS x UNION ALL 9038c08e861Sdrh SELECT -10 AS x); 9048c08e861Sdrh } 9058c08e861Sdrh} {1 {integer overflow}} 9068c08e861Sdrhdo_test func-18.19 { 9078c08e861Sdrh catchsql { 9088c08e861Sdrh SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x); 9098c08e861Sdrh } 9108c08e861Sdrh} {0 -1} 9118c08e861Sdrhdo_test func-18.20 { 9128c08e861Sdrh catchsql { 9138c08e861Sdrh SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x); 9148c08e861Sdrh } 9158c08e861Sdrh} {0 1} 9168c08e861Sdrhdo_test func-18.21 { 9178c08e861Sdrh catchsql { 9188c08e861Sdrh SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x); 9198c08e861Sdrh } 9208c08e861Sdrh} {0 -1} 9218c08e861Sdrhdo_test func-18.22 { 9228c08e861Sdrh catchsql { 9238c08e861Sdrh SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x); 9248c08e861Sdrh } 9258c08e861Sdrh} {0 1} 92676c730c1Sdrh 9274b2688abSdanielk1977} ;# ifcapable compound&&subquery 9284b2688abSdanielk1977 92952fc849aSdrh# Integer overflow on abs() 93052fc849aSdrh# 931fbd60f82Sshaneif {[working_64bit_int]} { 93252fc849aSdrh do_test func-18.31 { 93352fc849aSdrh catchsql { 93452fc849aSdrh SELECT abs(-9223372036854775807); 93552fc849aSdrh } 93652fc849aSdrh } {0 9223372036854775807} 937fbd60f82Sshane} 93852fc849aSdrhdo_test func-18.32 { 93952fc849aSdrh catchsql { 94052fc849aSdrh SELECT abs(-9223372036854775807-1); 94152fc849aSdrh } 94252fc849aSdrh} {1 {integer overflow}} 94352fc849aSdrh 9447f375901Sdrh# The MATCH function exists but is only a stub and always throws an error. 9457f375901Sdrh# 9467f375901Sdrhdo_test func-19.1 { 9477f375901Sdrh execsql { 9487f375901Sdrh SELECT match(a,b) FROM t1 WHERE 0; 9497f375901Sdrh } 9507f375901Sdrh} {} 9517f375901Sdrhdo_test func-19.2 { 9527f375901Sdrh catchsql { 9537f375901Sdrh SELECT 'abc' MATCH 'xyz'; 9547f375901Sdrh } 955b7481e70Sdrh} {1 {unable to use function MATCH in the requested context}} 9567f375901Sdrhdo_test func-19.3 { 9577f375901Sdrh catchsql { 9587f375901Sdrh SELECT 'abc' NOT MATCH 'xyz'; 9597f375901Sdrh } 960b7481e70Sdrh} {1 {unable to use function MATCH in the requested context}} 9617f375901Sdrhdo_test func-19.4 { 9627f375901Sdrh catchsql { 9637f375901Sdrh SELECT match(1,2,3); 9647f375901Sdrh } 9657f375901Sdrh} {1 {wrong number of arguments to function match()}} 96676c730c1Sdrh 967bdf67e0eSdrh# Soundex tests. 968bdf67e0eSdrh# 969bdf67e0eSdrhif {![catch {db eval {SELECT soundex('hello')}}]} { 970bdf67e0eSdrh set i 0 971bdf67e0eSdrh foreach {name sdx} { 972bdf67e0eSdrh euler E460 973bdf67e0eSdrh EULER E460 974bdf67e0eSdrh Euler E460 975bdf67e0eSdrh ellery E460 976bdf67e0eSdrh gauss G200 977bdf67e0eSdrh ghosh G200 978bdf67e0eSdrh hilbert H416 979bdf67e0eSdrh Heilbronn H416 980bdf67e0eSdrh knuth K530 981bdf67e0eSdrh kant K530 982bdf67e0eSdrh Lloyd L300 983bdf67e0eSdrh LADD L300 984bdf67e0eSdrh Lukasiewicz L222 985bdf67e0eSdrh Lissajous L222 986bdf67e0eSdrh A A000 987bdf67e0eSdrh 12345 ?000 988bdf67e0eSdrh } { 989bdf67e0eSdrh incr i 990bdf67e0eSdrh do_test func-20.$i { 991bdf67e0eSdrh execsql {SELECT soundex($name)} 992bdf67e0eSdrh } $sdx 993bdf67e0eSdrh } 994bdf67e0eSdrh} 995bdf67e0eSdrh 99626b6d90dSdrh# Tests of the REPLACE function. 99726b6d90dSdrh# 99826b6d90dSdrhdo_test func-21.1 { 99926b6d90dSdrh catchsql { 100026b6d90dSdrh SELECT replace(1,2); 100126b6d90dSdrh } 100226b6d90dSdrh} {1 {wrong number of arguments to function replace()}} 100326b6d90dSdrhdo_test func-21.2 { 100426b6d90dSdrh catchsql { 100526b6d90dSdrh SELECT replace(1,2,3,4); 100626b6d90dSdrh } 100726b6d90dSdrh} {1 {wrong number of arguments to function replace()}} 100826b6d90dSdrhdo_test func-21.3 { 100926b6d90dSdrh execsql { 1010*7d44b22dSdrh SELECT typeof(replace('This is the main test string', NULL, 'ALT')); 101126b6d90dSdrh } 101226b6d90dSdrh} {null} 101326b6d90dSdrhdo_test func-21.4 { 101426b6d90dSdrh execsql { 1015*7d44b22dSdrh SELECT typeof(replace(NULL, 'main', 'ALT')); 101626b6d90dSdrh } 101726b6d90dSdrh} {null} 101826b6d90dSdrhdo_test func-21.5 { 101926b6d90dSdrh execsql { 1020*7d44b22dSdrh SELECT typeof(replace('This is the main test string', 'main', NULL)); 102126b6d90dSdrh } 102226b6d90dSdrh} {null} 102326b6d90dSdrhdo_test func-21.6 { 102426b6d90dSdrh execsql { 1025*7d44b22dSdrh SELECT replace('This is the main test string', 'main', 'ALT'); 102626b6d90dSdrh } 102726b6d90dSdrh} {{This is the ALT test string}} 102826b6d90dSdrhdo_test func-21.7 { 102926b6d90dSdrh execsql { 1030*7d44b22dSdrh SELECT replace('This is the main test string', 'main', 'larger-main'); 103126b6d90dSdrh } 103226b6d90dSdrh} {{This is the larger-main test string}} 103326b6d90dSdrhdo_test func-21.8 { 103426b6d90dSdrh execsql { 1035*7d44b22dSdrh SELECT replace('aaaaaaa', 'a', '0123456789'); 103626b6d90dSdrh } 103726b6d90dSdrh} {0123456789012345678901234567890123456789012345678901234567890123456789} 103826b6d90dSdrh 10394152e677Sdanielk1977ifcapable tclvar { 104017374e8fSdanielk1977 do_test func-21.9 { 104117374e8fSdanielk1977 # Attempt to exploit a buffer-overflow that at one time existed 104217374e8fSdanielk1977 # in the REPLACE function. 104317374e8fSdanielk1977 set ::str "[string repeat A 29998]CC[string repeat A 35537]" 104417374e8fSdanielk1977 set ::rep [string repeat B 65536] 104517374e8fSdanielk1977 execsql { 104617374e8fSdanielk1977 SELECT LENGTH(REPLACE($::str, 'C', $::rep)); 104717374e8fSdanielk1977 } 104817374e8fSdanielk1977 } [expr 29998 + 2*65536 + 35537] 10494152e677Sdanielk1977} 105017374e8fSdanielk1977 1051309b3386Sdrh# Tests for the TRIM, LTRIM and RTRIM functions. 1052309b3386Sdrh# 1053309b3386Sdrhdo_test func-22.1 { 1054309b3386Sdrh catchsql {SELECT trim(1,2,3)} 1055309b3386Sdrh} {1 {wrong number of arguments to function trim()}} 1056309b3386Sdrhdo_test func-22.2 { 1057309b3386Sdrh catchsql {SELECT ltrim(1,2,3)} 1058309b3386Sdrh} {1 {wrong number of arguments to function ltrim()}} 1059309b3386Sdrhdo_test func-22.3 { 1060309b3386Sdrh catchsql {SELECT rtrim(1,2,3)} 1061309b3386Sdrh} {1 {wrong number of arguments to function rtrim()}} 1062309b3386Sdrhdo_test func-22.4 { 1063309b3386Sdrh execsql {SELECT trim(' hi ');} 1064309b3386Sdrh} {hi} 1065309b3386Sdrhdo_test func-22.5 { 1066309b3386Sdrh execsql {SELECT ltrim(' hi ');} 1067309b3386Sdrh} {{hi }} 1068309b3386Sdrhdo_test func-22.6 { 1069309b3386Sdrh execsql {SELECT rtrim(' hi ');} 1070309b3386Sdrh} {{ hi}} 1071309b3386Sdrhdo_test func-22.7 { 1072309b3386Sdrh execsql {SELECT trim(' hi ','xyz');} 1073309b3386Sdrh} {{ hi }} 1074309b3386Sdrhdo_test func-22.8 { 1075309b3386Sdrh execsql {SELECT ltrim(' hi ','xyz');} 1076309b3386Sdrh} {{ hi }} 1077309b3386Sdrhdo_test func-22.9 { 1078309b3386Sdrh execsql {SELECT rtrim(' hi ','xyz');} 1079309b3386Sdrh} {{ hi }} 1080309b3386Sdrhdo_test func-22.10 { 1081309b3386Sdrh execsql {SELECT trim('xyxzy hi zzzy','xyz');} 1082309b3386Sdrh} {{ hi }} 1083309b3386Sdrhdo_test func-22.11 { 1084309b3386Sdrh execsql {SELECT ltrim('xyxzy hi zzzy','xyz');} 1085309b3386Sdrh} {{ hi zzzy}} 1086309b3386Sdrhdo_test func-22.12 { 1087309b3386Sdrh execsql {SELECT rtrim('xyxzy hi zzzy','xyz');} 1088309b3386Sdrh} {{xyxzy hi }} 1089309b3386Sdrhdo_test func-22.13 { 1090309b3386Sdrh execsql {SELECT trim(' hi ','');} 1091309b3386Sdrh} {{ hi }} 10924e05c83bSdrhif {[db one {PRAGMA encoding}]=="UTF-8"} { 1093d1e3a616Sdrh do_test func-22.14 { 10947a928d75Sdrh execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))} 10957a928d75Sdrh } {F48FBFBF6869} 1096d1e3a616Sdrh do_test func-22.15 { 10977a928d75Sdrh execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61', 10987a928d75Sdrh x'6162e1bfbfc280f48fbfbf'))} 1099d1e3a616Sdrh } {6869} 1100d1e3a616Sdrh do_test func-22.16 { 1101d1e3a616Sdrh execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));} 1102d1e3a616Sdrh } {CEB2CEB3} 11034e05c83bSdrh} 1104309b3386Sdrhdo_test func-22.20 { 1105309b3386Sdrh execsql {SELECT typeof(trim(NULL));} 1106309b3386Sdrh} {null} 1107309b3386Sdrhdo_test func-22.21 { 1108309b3386Sdrh execsql {SELECT typeof(trim(NULL,'xyz'));} 1109309b3386Sdrh} {null} 1110309b3386Sdrhdo_test func-22.22 { 1111309b3386Sdrh execsql {SELECT typeof(trim('hello',NULL));} 1112309b3386Sdrh} {null} 111326b6d90dSdrh 1114972da427Sdrh# 2021-06-15 - infinite loop due to unsigned character counter 1115972da427Sdrh# overflow, reported by Zimuzo Ezeozue 1116972da427Sdrh# 1117972da427Sdrhdo_execsql_test func-22.23 { 1118972da427Sdrh SELECT trim('xyzzy',x'c0808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080'); 1119972da427Sdrh} {xyzzy} 1120972da427Sdrh 1121fa18beceSdanielk1977# This is to test the deprecated sqlite3_aggregate_count() API. 1122fa18beceSdanielk1977# 1123eec556d3Sshaneifcapable deprecated { 1124fa18beceSdanielk1977 do_test func-23.1 { 1125fa18beceSdanielk1977 sqlite3_create_aggregate db 1126fa18beceSdanielk1977 execsql { 1127fa18beceSdanielk1977 SELECT legacy_count() FROM t6; 1128fa18beceSdanielk1977 } 1129fa18beceSdanielk1977 } {3} 1130eec556d3Sshane} 1131fa18beceSdanielk1977 1132ade86483Sdrh# The group_concat() function. 1133ade86483Sdrh# 1134ade86483Sdrhdo_test func-24.1 { 1135ade86483Sdrh execsql { 1136ade86483Sdrh SELECT group_concat(t1) FROM tbl1 1137ade86483Sdrh } 1138ade86483Sdrh} {this,program,is,free,software} 1139ade86483Sdrhdo_test func-24.2 { 1140ade86483Sdrh execsql { 1141ade86483Sdrh SELECT group_concat(t1,' ') FROM tbl1 1142ade86483Sdrh } 1143ade86483Sdrh} {{this program is free software}} 1144ade86483Sdrhdo_test func-24.3 { 1145ade86483Sdrh execsql { 1146ade86483Sdrh SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1 1147ade86483Sdrh } 1148ade86483Sdrh} {{this 2 program 3 is 4 free 5 software}} 1149ade86483Sdrhdo_test func-24.4 { 1150ade86483Sdrh execsql { 1151ade86483Sdrh SELECT group_concat(NULL,t1) FROM tbl1 1152ade86483Sdrh } 1153ade86483Sdrh} {{}} 1154ade86483Sdrhdo_test func-24.5 { 1155ade86483Sdrh execsql { 1156ade86483Sdrh SELECT group_concat(t1,NULL) FROM tbl1 1157ade86483Sdrh } 1158ade86483Sdrh} {thisprogramisfreesoftware} 11592dca8680Sdrhdo_test func-24.6 { 11602dca8680Sdrh execsql { 11612dca8680Sdrh SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 11622dca8680Sdrh } 11632dca8680Sdrh} {BEGIN-this,program,is,free,software} 116407d3117aSdrh 116507d3117aSdrh# Ticket #3179: Make sure aggregate functions can take many arguments. 116607d3117aSdrh# None of the built-in aggregates do this, so use the md5sum() from the 116707d3117aSdrh# test extensions. 116807d3117aSdrh# 11693780b5deSdrhunset -nocomplain midargs 1170a2baf3a2Sdrhset midargs {} 11713780b5deSdrhunset -nocomplain midres 1172a2baf3a2Sdrhset midres {} 11733780b5deSdrhunset -nocomplain result 117407d3117aSdrhfor {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} { 1175a2baf3a2Sdrh append midargs ,'/$i' 1176a2baf3a2Sdrh append midres /$i 117707d3117aSdrh set result [md5 \ 117807d3117aSdrh "this${midres}program${midres}is${midres}free${midres}software${midres}"] 117907d3117aSdrh set sql "SELECT md5sum(t1$midargs) FROM tbl1" 1180a2baf3a2Sdrh do_test func-24.7.$i { 1181a2baf3a2Sdrh db eval $::sql 1182a2baf3a2Sdrh } $result 1183a2baf3a2Sdrh} 1184ade86483Sdrh 11858dc09a06Sdrh# Ticket #3806. If the initial string in a group_concat is an empty 11868bfd7190Sdrh# string, the separator that follows should still be present. 11878dc09a06Sdrh# 11888dc09a06Sdrhdo_test func-24.8 { 11898dc09a06Sdrh execsql { 11908dc09a06Sdrh SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1 11918dc09a06Sdrh } 11928dc09a06Sdrh} {,program,is,free,software} 11938dc09a06Sdrhdo_test func-24.9 { 11948dc09a06Sdrh execsql { 11958dc09a06Sdrh SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1 11968dc09a06Sdrh } 11978dc09a06Sdrh} {,,,,software} 11988dc09a06Sdrh 11998bfd7190Sdrh# Ticket #3923. Initial empty strings have a separator. But initial 12008bfd7190Sdrh# NULLs do not. 12018bfd7190Sdrh# 12028bfd7190Sdrhdo_test func-24.10 { 12038bfd7190Sdrh execsql { 12048bfd7190Sdrh SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1 12058bfd7190Sdrh } 12068bfd7190Sdrh} {program,is,free,software} 12078bfd7190Sdrhdo_test func-24.11 { 12088bfd7190Sdrh execsql { 12098bfd7190Sdrh SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1 12108bfd7190Sdrh } 12118bfd7190Sdrh} {software} 12128bfd7190Sdrhdo_test func-24.12 { 12138bfd7190Sdrh execsql { 12148bfd7190Sdrh SELECT group_concat(CASE t1 WHEN 'this' THEN '' 12158bfd7190Sdrh WHEN 'program' THEN null ELSE t1 END) FROM tbl1 12168bfd7190Sdrh } 12178bfd7190Sdrh} {,is,free,software} 1218eacc050fSdrh# Tests to verify ticket http://www.sqlite.org/src/tktview/55746f9e65f8587c0 1219eacc050fSdrhdo_test func-24.13 { 1220eacc050fSdrh execsql { 1221eacc050fSdrh SELECT typeof(group_concat(x)) FROM (SELECT '' AS x); 1222eacc050fSdrh } 1223eacc050fSdrh} {text} 1224eacc050fSdrhdo_test func-24.14 { 1225eacc050fSdrh execsql { 1226eacc050fSdrh SELECT typeof(group_concat(x,'')) 1227eacc050fSdrh FROM (SELECT '' AS x UNION ALL SELECT ''); 1228eacc050fSdrh } 1229eacc050fSdrh} {text} 12308bfd7190Sdrh 12318bfd7190Sdrh 1232191b54cbSdrh# Use the test_isolation function to make sure that type conversions 1233191b54cbSdrh# on function arguments do not effect subsequent arguments. 1234191b54cbSdrh# 1235191b54cbSdrhdo_test func-25.1 { 1236191b54cbSdrh execsql {SELECT test_isolation(t1,t1) FROM tbl1} 1237191b54cbSdrh} {this program is free software} 1238191b54cbSdrh 123924b58dd7Sdrh# Try to misuse the sqlite3_create_function() interface. Verify that 124024b58dd7Sdrh# errors are returned. 124124b58dd7Sdrh# 124224b58dd7Sdrhdo_test func-26.1 { 124324b58dd7Sdrh abuse_create_function db 124424b58dd7Sdrh} {} 124524b58dd7Sdrh 124624b58dd7Sdrh# The previous test (func-26.1) registered a function with a very long 124724b58dd7Sdrh# function name that takes many arguments and always returns NULL. Verify 124824b58dd7Sdrh# that this function works correctly. 124924b58dd7Sdrh# 125024b58dd7Sdrhdo_test func-26.2 { 125124b58dd7Sdrh set a {} 125224b58dd7Sdrh for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} { 125324b58dd7Sdrh lappend a $i 125424b58dd7Sdrh } 125524b58dd7Sdrh db eval " 125624b58dd7Sdrh 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 ,]); 125724b58dd7Sdrh " 125824b58dd7Sdrh} {{}} 125924b58dd7Sdrhdo_test func-26.3 { 126024b58dd7Sdrh set a {} 126124b58dd7Sdrh for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} { 126224b58dd7Sdrh lappend a $i 126324b58dd7Sdrh } 126424b58dd7Sdrh catchsql " 126524b58dd7Sdrh 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 ,]); 126624b58dd7Sdrh " 126724b58dd7Sdrh} {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}} 126824b58dd7Sdrhdo_test func-26.4 { 126924b58dd7Sdrh set a {} 127024b58dd7Sdrh for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} { 127124b58dd7Sdrh lappend a $i 127224b58dd7Sdrh } 127324b58dd7Sdrh catchsql " 127424b58dd7Sdrh 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 ,]); 127524b58dd7Sdrh " 127624b58dd7Sdrh} {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()}} 127724b58dd7Sdrhdo_test func-26.5 { 127824b58dd7Sdrh catchsql " 127924b58dd7Sdrh 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); 128024b58dd7Sdrh " 128124b58dd7Sdrh} {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}} 128224b58dd7Sdrhdo_test func-26.6 { 128324b58dd7Sdrh catchsql " 128424b58dd7Sdrh 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); 128524b58dd7Sdrh " 128624b58dd7Sdrh} {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}} 128724b58dd7Sdrh 1288dfbc3a8aSdrhdo_test func-27.1 { 1289dfbc3a8aSdrh catchsql {SELECT coalesce()} 1290dfbc3a8aSdrh} {1 {wrong number of arguments to function coalesce()}} 1291dfbc3a8aSdrhdo_test func-27.2 { 1292dfbc3a8aSdrh catchsql {SELECT coalesce(1)} 1293dfbc3a8aSdrh} {1 {wrong number of arguments to function coalesce()}} 1294dfbc3a8aSdrhdo_test func-27.3 { 1295dfbc3a8aSdrh catchsql {SELECT coalesce(1,2)} 1296dfbc3a8aSdrh} {0 1} 1297dfbc3a8aSdrh 1298feb306f5Sdrh# Ticket 2d401a94287b5 1299feb306f5Sdrh# Unknown function in a DEFAULT expression causes a segfault. 1300feb306f5Sdrh# 1301feb306f5Sdrhdo_test func-28.1 { 1302feb306f5Sdrh db eval { 1303feb306f5Sdrh CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1))); 1304feb306f5Sdrh } 1305feb306f5Sdrh catchsql { 1306feb306f5Sdrh INSERT INTO t28(x) VALUES(1); 1307feb306f5Sdrh } 1308feb306f5Sdrh} {1 {unknown function: nosuchfunc()}} 1309feb306f5Sdrh 1310a748fdccSdrh# Verify that the length() and typeof() functions do not actually load 1311a748fdccSdrh# the content of their argument. 1312a748fdccSdrh# 1313a748fdccSdrhdo_test func-29.1 { 1314a748fdccSdrh db eval { 1315a748fdccSdrh CREATE TABLE t29(id INTEGER PRIMARY KEY, x, y); 1316a748fdccSdrh INSERT INTO t29 VALUES(1, 2, 3), (2, NULL, 4), (3, 4.5, 5); 1317a748fdccSdrh INSERT INTO t29 VALUES(4, randomblob(1000000), 6); 1318*7d44b22dSdrh INSERT INTO t29 VALUES(5, 'hello', 7); 1319a748fdccSdrh } 1320a748fdccSdrh db close 1321a748fdccSdrh sqlite3 db test.db 1322a748fdccSdrh sqlite3_db_status db CACHE_MISS 1 1323a748fdccSdrh db eval {SELECT typeof(x), length(x), typeof(y) FROM t29 ORDER BY id} 1324a748fdccSdrh} {integer 1 integer null {} integer real 3 integer blob 1000000 integer text 5 integer} 1325a748fdccSdrhdo_test func-29.2 { 1326a748fdccSdrh set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] 1327a748fdccSdrh if {$x<5} {set x 1} 1328a748fdccSdrh set x 1329a748fdccSdrh} {1} 1330a748fdccSdrhdo_test func-29.3 { 1331a748fdccSdrh db close 1332a748fdccSdrh sqlite3 db test.db 1333a748fdccSdrh sqlite3_db_status db CACHE_MISS 1 1334a748fdccSdrh db eval {SELECT typeof(+x) FROM t29 ORDER BY id} 1335a748fdccSdrh} {integer null real blob text} 13369b4c59faSdrhif {[permutation] != "mmap"} { 13379bc21b53Sdan ifcapable !direct_read { 1338a748fdccSdrh do_test func-29.4 { 1339a748fdccSdrh set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] 1340a748fdccSdrh if {$x>100} {set x many} 1341a748fdccSdrh set x 1342a748fdccSdrh } {many} 13435d8a1372Sdan } 13449bc21b53Sdan} 13453c888b7dSdrhdo_test func-29.5 { 13463c888b7dSdrh db close 13473c888b7dSdrh sqlite3 db test.db 13483c888b7dSdrh sqlite3_db_status db CACHE_MISS 1 13493c888b7dSdrh db eval {SELECT sum(length(x)) FROM t29} 13503c888b7dSdrh} {1000009} 13513c888b7dSdrhdo_test func-29.6 { 13523c888b7dSdrh set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1] 13533c888b7dSdrh if {$x<5} {set x 1} 13543c888b7dSdrh set x 13553c888b7dSdrh} {1} 1356a748fdccSdrh 1357380d6851Sdrh# The OP_Column opcode has an optimization that avoids loading content 1358380d6851Sdrh# for fields with content-length=0 when the content offset is on an overflow 1359380d6851Sdrh# page. Make sure the optimization works. 1360380d6851Sdrh# 1361380d6851Sdrhdo_execsql_test func-29.10 { 1362380d6851Sdrh CREATE TABLE t29b(a,b,c,d,e,f,g,h,i); 1363380d6851Sdrh INSERT INTO t29b 1364380d6851Sdrh VALUES(1, hex(randomblob(2000)), null, 0, 1, '', zeroblob(0),'x',x'01'); 1365380d6851Sdrh SELECT typeof(c), typeof(d), typeof(e), typeof(f), 1366380d6851Sdrh typeof(g), typeof(h), typeof(i) FROM t29b; 1367380d6851Sdrh} {null integer integer text blob text blob} 1368380d6851Sdrhdo_execsql_test func-29.11 { 1369380d6851Sdrh SELECT length(f), length(g), length(h), length(i) FROM t29b; 1370380d6851Sdrh} {0 0 1 1} 1371380d6851Sdrhdo_execsql_test func-29.12 { 1372380d6851Sdrh SELECT quote(f), quote(g), quote(h), quote(i) FROM t29b; 1373380d6851Sdrh} {'' X'' 'x' X'01'} 1374380d6851Sdrh 13753432daa8Sdrh# EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric 13763432daa8Sdrh# unicode code point corresponding to the first character of the string 13773432daa8Sdrh# X. 13783432daa8Sdrh# 13793432daa8Sdrh# EVIDENCE-OF: R-55469-62130 The char(X1,X2,...,XN) function returns a 13803432daa8Sdrh# string composed of characters having the unicode code point values of 13813432daa8Sdrh# integers X1 through XN, respectively. 13823432daa8Sdrh# 1383d495d8c9Sdrhdo_execsql_test func-30.1 {SELECT unicode('$');} 36 13848d0b81d7Smistachkindo_execsql_test func-30.2 [subst {SELECT unicode('\u00A2');}] 162 13858d0b81d7Smistachkindo_execsql_test func-30.3 [subst {SELECT unicode('\u20AC');}] 8364 13868d0b81d7Smistachkindo_execsql_test func-30.4 {SELECT char(36,162,8364);} [subst {$\u00A2\u20AC}] 1387a748fdccSdrh 1388fbc1ddf0Sdrhfor {set i 1} {$i<0xd800} {incr i 13} { 1389fbc1ddf0Sdrh do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i 1390fbc1ddf0Sdrh} 1391fbc1ddf0Sdrhfor {set i 57344} {$i<=0xfffd} {incr i 17} { 1392fbc1ddf0Sdrh if {$i==0xfeff} continue 1393fbc1ddf0Sdrh do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i 1394fbc1ddf0Sdrh} 1395fbc1ddf0Sdrhfor {set i 65536} {$i<=0x10ffff} {incr i 139} { 1396fbc1ddf0Sdrh do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i 1397fbc1ddf0Sdrh} 1398ff6e9116Sdrh 1399b72cad14Sdan# Test char(). 1400b72cad14Sdan# 1401b72cad14Sdando_execsql_test func-31.1 { 1402b72cad14Sdan SELECT char(), length(char()), typeof(char()) 1403b72cad14Sdan} {{} 0 text} 140457b1a3e3Sdrh 140557b1a3e3Sdrh# sqlite3_value_frombind() 140657b1a3e3Sdrh# 140757b1a3e3Sdrhdo_execsql_test func-32.100 { 140857b1a3e3Sdrh SELECT test_frombind(1,2,3,4); 140957b1a3e3Sdrh} {0} 141057b1a3e3Sdrhdo_execsql_test func-32.110 { 141157b1a3e3Sdrh SELECT test_frombind(1,2,?,4); 141257b1a3e3Sdrh} {4} 141357b1a3e3Sdrhdo_execsql_test func-32.120 { 141457b1a3e3Sdrh SELECT test_frombind(1,(?),4,?+7); 141557b1a3e3Sdrh} {2} 141657b1a3e3Sdrhdo_execsql_test func-32.130 { 141757b1a3e3Sdrh DROP TABLE IF EXISTS t1; 141857b1a3e3Sdrh CREATE TABLE t1(a,b,c,e,f); 141957b1a3e3Sdrh INSERT INTO t1 VALUES(1,2.5,'xyz',x'e0c1b2a3',null); 142057b1a3e3Sdrh SELECT test_frombind(a,b,c,e,f,$xyz) FROM t1; 142157b1a3e3Sdrh} {32} 142257b1a3e3Sdrhdo_execsql_test func-32.140 { 142357b1a3e3Sdrh SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1; 142457b1a3e3Sdrh} {0} 142557b1a3e3Sdrhdo_execsql_test func-32.150 { 142657b1a3e3Sdrh SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y; 142757b1a3e3Sdrh} {8} 142857b1a3e3Sdrh 142942d2fce7Sdrh# 2019-08-15 143042d2fce7Sdrh# Direct-only functions. 143142d2fce7Sdrh# 143242d2fce7Sdrhproc testdirectonly {x} {return [expr {$x*2}]} 143342d2fce7Sdrhdo_test func-33.1 { 143442d2fce7Sdrh db func testdirectonly -directonly testdirectonly 143542d2fce7Sdrh db eval {SELECT testdirectonly(15)} 143642d2fce7Sdrh} {30} 143742d2fce7Sdrhdo_catchsql_test func-33.2 { 143842d2fce7Sdrh CREATE VIEW v33(y) AS SELECT testdirectonly(15); 143942d2fce7Sdrh SELECT * FROM v33; 14400dfa5255Sdrh} {1 {unsafe use of testdirectonly()}} 144142d2fce7Sdrhdo_execsql_test func-33.3 { 144242d2fce7Sdrh SELECT * FROM (SELECT testdirectonly(15)) AS v33; 144342d2fce7Sdrh} {30} 144442d2fce7Sdrhdo_execsql_test func-33.4 { 144542d2fce7Sdrh WITH c(x) AS (SELECT testdirectonly(15)) 144642d2fce7Sdrh SELECT * FROM c; 144742d2fce7Sdrh} {30} 144842d2fce7Sdrhdo_catchsql_test func-33.5 { 144942d2fce7Sdrh WITH c(x) AS (SELECT * FROM v33) 145042d2fce7Sdrh SELECT * FROM c; 14510dfa5255Sdrh} {1 {unsafe use of testdirectonly()}} 145242d2fce7Sdrhdo_execsql_test func-33.10 { 145342d2fce7Sdrh CREATE TABLE t33a(a,b); 145442d2fce7Sdrh CREATE TABLE t33b(x,y); 145542d2fce7Sdrh CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN 145642d2fce7Sdrh INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b); 145742d2fce7Sdrh END; 145842d2fce7Sdrh} {} 145942d2fce7Sdrhdo_catchsql_test func-33.11 { 146042d2fce7Sdrh INSERT INTO t33a VALUES(1,2); 14610dfa5255Sdrh} {1 {unsafe use of testdirectonly()}} 146237f3ac8fSdan 146337f3ac8fSdanifcapable altertable { 146442d2fce7Sdrhdo_execsql_test func-33.20 { 146542d2fce7Sdrh ALTER TABLE t33a RENAME COLUMN a TO aaa; 146642d2fce7Sdrh SELECT sql FROM sqlite_master WHERE name='r1'; 146742d2fce7Sdrh} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN 146842d2fce7Sdrh INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b); 146942d2fce7Sdrh END}} 147037f3ac8fSdan} 147157b1a3e3Sdrh 1472b2fe5a7cSdrh# 2020-01-09 Yongheng fuzzer find 1473b2fe5a7cSdrh# The bug is in the register-validity debug logic, not in the SQLite core 1474b2fe5a7cSdrh# and as such it only impacts debug builds. Release builds work fine. 1475b2fe5a7cSdrh# 1476b2fe5a7cSdrhreset_db 1477b2fe5a7cSdrhdo_execsql_test func-34.10 { 1478b2fe5a7cSdrh CREATE TABLE t1(a INT CHECK( 1479b2fe5a7cSdrh datetime( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1480b2fe5a7cSdrh 10,11,12,13,14,15,16,17,18,19, 1481b2fe5a7cSdrh 20,21,22,23,24,25,26,27,28,29, 1482b2fe5a7cSdrh 30,31,32,33,34,35,36,37,38,39, 1483b2fe5a7cSdrh 40,41,42,43,44,45,46,47,48,a) 1484b2fe5a7cSdrh ) 1485b2fe5a7cSdrh ); 1486b2fe5a7cSdrh INSERT INTO t1(a) VALUES(1),(2); 1487b2fe5a7cSdrh SELECT * FROM t1; 1488b2fe5a7cSdrh} {1 2} 148957b1a3e3Sdrh 14909b258c54Sdrh# 2020-03-11 COALESCE() should short-circuit 14919b258c54Sdrh# See also ticket 3c9eadd2a6ba0aa5 14929b258c54Sdrh# Both issues stem from the fact that functions that could 14939b258c54Sdrh# throw exceptions were being factored out into initialization 14949b258c54Sdrh# code. The fix was to put those function calls inside of 14959b258c54Sdrh# OP_Once instead. 14969b258c54Sdrh# 14979b258c54Sdrhreset_db 14989b258c54Sdrhdo_execsql_test func-35.100 { 14999b258c54Sdrh CREATE TABLE t1(x); 15009b258c54Sdrh SELECT coalesce(x, abs(-9223372036854775808)) FROM t1; 15019b258c54Sdrh} {} 15029b258c54Sdrhdo_execsql_test func-35.110 { 15039b258c54Sdrh SELECT coalesce(x, 'xyz' LIKE printf('%.1000000c','y')) FROM t1; 15049b258c54Sdrh} {} 15059b258c54Sdrhdo_execsql_test func-35.200 { 15069b258c54Sdrh CREATE TABLE t0(c0 CHECK(ABS(-9223372036854775808))); 15079b258c54Sdrh PRAGMA integrity_check; 15089b258c54Sdrh} {ok} 15099b258c54Sdrh 1510d5326c33Sdrh# 2021-01-07: The -> and ->> operators. 1511d5326c33Sdrh# 1512d5326c33Sdrhproc ptr1 {a b} { return "$a->$b" } 1513d5326c33Sdrhdb func -> ptr1 1514d5326c33Sdrhproc ptr2 {a b} { return "$a->>$b" } 1515d5326c33Sdrhdb func ->> ptr2 1516d5326c33Sdrhdo_execsql_test func-36.100 { 1517d5326c33Sdrh SELECT 123 -> 456 1518d5326c33Sdrh} {123->456} 1519d5326c33Sdrhdo_execsql_test func-36.110 { 1520d5326c33Sdrh SELECT 123 ->> 456 1521d5326c33Sdrh} {123->>456} 1522d5326c33Sdrh 1523d5326c33Sdrh 1524d5326c33Sdrh 1525ff6e9116Sdrhfinish_test 1526