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# 14*dfbc3a8aSdrh# $Id: func.test,v 1.88 2009/01/31 22:28:49 drh Exp $ 15ff6e9116Sdrh 16ff6e9116Sdrhset testdir [file dirname $argv0] 17ff6e9116Sdrhsource $testdir/tester.tcl 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# 152bf4133cbSdrhdo_test func-4.1 { 153bf4133cbSdrh execsql { 154bf4133cbSdrh CREATE TABLE t1(a,b,c); 155bf4133cbSdrh INSERT INTO t1 VALUES(1,2,3); 156bf4133cbSdrh INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890); 157bf4133cbSdrh INSERT INTO t1 VALUES(3,-2,-5); 158bf4133cbSdrh } 159bf4133cbSdrh catchsql {SELECT abs(a,b) FROM t1} 16089425d5eSdrh} {1 {wrong number of arguments to function abs()}} 161bf4133cbSdrhdo_test func-4.2 { 162bf4133cbSdrh catchsql {SELECT abs() FROM t1} 16389425d5eSdrh} {1 {wrong number of arguments to function abs()}} 164bf4133cbSdrhdo_test func-4.3 { 165bf4133cbSdrh catchsql {SELECT abs(b) FROM t1 ORDER BY a} 166bf4133cbSdrh} {0 {2 1.2345678901234 2}} 167bf4133cbSdrhdo_test func-4.4 { 168bf4133cbSdrh catchsql {SELECT abs(c) FROM t1 ORDER BY a} 1693d1bfeaaSdanielk1977} {0 {3 12345.6789 5}} 170832508b7Sdrhdo_test func-4.4.1 { 171832508b7Sdrh execsql {SELECT abs(a) FROM t2} 172832508b7Sdrh} {1 {} 345 {} 67890} 173832508b7Sdrhdo_test func-4.4.2 { 174832508b7Sdrh execsql {SELECT abs(t1) FROM tbl1} 17592febd92Sdrh} {0.0 0.0 0.0 0.0 0.0} 176bf4133cbSdrh 177bf4133cbSdrhdo_test func-4.5 { 178bf4133cbSdrh catchsql {SELECT round(a,b,c) FROM t1} 17989425d5eSdrh} {1 {wrong number of arguments to function round()}} 180bf4133cbSdrhdo_test func-4.6 { 1818aff1015Sdrh catchsql {SELECT round(b,2) FROM t1 ORDER BY b} 182d589a92aSdrh} {0 {-2.0 1.23 2.0}} 183bf4133cbSdrhdo_test func-4.7 { 184bf4133cbSdrh catchsql {SELECT round(b,0) FROM t1 ORDER BY a} 185d589a92aSdrh} {0 {2.0 1.0 -2.0}} 186bf4133cbSdrhdo_test func-4.8 { 187bf4133cbSdrh catchsql {SELECT round(c) FROM t1 ORDER BY a} 188d589a92aSdrh} {0 {3.0 -12346.0 -5.0}} 189bf4133cbSdrhdo_test func-4.9 { 190bf4133cbSdrh catchsql {SELECT round(c,a) FROM t1 ORDER BY a} 191d589a92aSdrh} {0 {3.0 -12345.68 -5.0}} 192bf4133cbSdrhdo_test func-4.10 { 19301a34661Sdrh catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a} 194d589a92aSdrh} {0 {x3.0y x-12345.68y x-5.0y}} 19501a34661Sdrhdo_test func-4.11 { 196bf4133cbSdrh catchsql {SELECT round() FROM t1 ORDER BY a} 19789425d5eSdrh} {1 {wrong number of arguments to function round()}} 198832508b7Sdrhdo_test func-4.12 { 199bb113518Sdrh execsql {SELECT coalesce(round(a,2),'nil') FROM t2} 200d589a92aSdrh} {1.0 nil 345.0 nil 67890.0} 201832508b7Sdrhdo_test func-4.13 { 202832508b7Sdrh execsql {SELECT round(t1,2) FROM tbl1} 203d589a92aSdrh} {0.0 0.0 0.0 0.0 0.0} 204d589a92aSdrhdo_test func-4.14 { 205d589a92aSdrh execsql {SELECT typeof(round(5.1,1));} 206d589a92aSdrh} {real} 207d589a92aSdrhdo_test func-4.15 { 208d589a92aSdrh execsql {SELECT typeof(round(5.1));} 209d589a92aSdrh} {real} 210d589a92aSdrh 211832508b7Sdrh 212832508b7Sdrh# Test the upper() and lower() functions 213832508b7Sdrh# 214832508b7Sdrhdo_test func-5.1 { 215832508b7Sdrh execsql {SELECT upper(t1) FROM tbl1} 216832508b7Sdrh} {THIS PROGRAM IS FREE SOFTWARE} 217832508b7Sdrhdo_test func-5.2 { 218832508b7Sdrh execsql {SELECT lower(upper(t1)) FROM tbl1} 219832508b7Sdrh} {this program is free software} 220832508b7Sdrhdo_test func-5.3 { 221832508b7Sdrh execsql {SELECT upper(a), lower(a) FROM t2} 222832508b7Sdrh} {1 1 {} {} 345 345 {} {} 67890 67890} 2237de68a09Sdanielk1977ifcapable !icu { 224832508b7Sdrh do_test func-5.4 { 225832508b7Sdrh catchsql {SELECT upper(a,5) FROM t2} 226832508b7Sdrh } {1 {wrong number of arguments to function upper()}} 2277de68a09Sdanielk1977} 228832508b7Sdrhdo_test func-5.5 { 229832508b7Sdrh catchsql {SELECT upper(*) FROM t2} 230832508b7Sdrh} {1 {wrong number of arguments to function upper()}} 231832508b7Sdrh 232a9f9d1c0Sdrh# Test the coalesce() and nullif() functions 233832508b7Sdrh# 234832508b7Sdrhdo_test func-6.1 { 235832508b7Sdrh execsql {SELECT coalesce(a,'xyz') FROM t2} 236832508b7Sdrh} {1 xyz 345 xyz 67890} 237832508b7Sdrhdo_test func-6.2 { 238832508b7Sdrh execsql {SELECT coalesce(upper(a),'nil') FROM t2} 239832508b7Sdrh} {1 nil 345 nil 67890} 240a9f9d1c0Sdrhdo_test func-6.3 { 241a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,1),'nil')} 242a9f9d1c0Sdrh} {nil} 243a9f9d1c0Sdrhdo_test func-6.4 { 244a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,2),'nil')} 245a9f9d1c0Sdrh} {1} 246a9f9d1c0Sdrhdo_test func-6.5 { 247a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,NULL),'nil')} 248a9f9d1c0Sdrh} {1} 249a9f9d1c0Sdrh 250832508b7Sdrh 2516ed41ad7Sdrh# Test the last_insert_rowid() function 2526ed41ad7Sdrh# 2536ed41ad7Sdrhdo_test func-7.1 { 2546ed41ad7Sdrh execsql {SELECT last_insert_rowid()} 2556ed41ad7Sdrh} [db last_insert_rowid] 2566ed41ad7Sdrh 257739105c7Sdrh# Tests for aggregate functions and how they handle NULLs. 258739105c7Sdrh# 259739105c7Sdrhdo_test func-8.1 { 2604489f9bdSdanielk1977 ifcapable explain { 261c5cdca61Sdrh execsql {EXPLAIN SELECT sum(a) FROM t2;} 2624489f9bdSdanielk1977 } 263739105c7Sdrh execsql { 264739105c7Sdrh SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2; 265739105c7Sdrh } 2663d1d95e6Sdrh} {68236 3 22745.33 1 67890 5} 267a9f9d1c0Sdrhdo_test func-8.2 { 268a9f9d1c0Sdrh execsql { 269a9f9d1c0Sdrh SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; 270a9f9d1c0Sdrh } 271a9f9d1c0Sdrh} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 27253c0f748Sdanielk1977 27353c0f748Sdanielk1977ifcapable tempdb { 274a9f9d1c0Sdrh do_test func-8.3 { 275a9f9d1c0Sdrh execsql { 276a9f9d1c0Sdrh CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 277a9f9d1c0Sdrh SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 278a9f9d1c0Sdrh } 2799eb516c0Sdrh } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 28053c0f748Sdanielk1977} else { 28153c0f748Sdanielk1977 do_test func-8.3 { 28253c0f748Sdanielk1977 execsql { 28353c0f748Sdanielk1977 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 28453c0f748Sdanielk1977 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 28553c0f748Sdanielk1977 } 28653c0f748Sdanielk1977 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 28753c0f748Sdanielk1977} 2883aeab9e4Sdanielk1977do_test func-8.4 { 2893aeab9e4Sdanielk1977 execsql { 2903aeab9e4Sdanielk1977 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 2913aeab9e4Sdanielk1977 } 2923aeab9e4Sdanielk1977} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 293de3e41e3Sdanielk1977ifcapable compound { 29485e9e22bSdrh do_test func-8.5 { 29585e9e22bSdrh execsql { 29685e9e22bSdrh SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x 29785e9e22bSdrh UNION ALL SELECT -9223372036854775807) 29885e9e22bSdrh } 29985e9e22bSdrh } {0} 30085e9e22bSdrh do_test func-8.6 { 30185e9e22bSdrh execsql { 30206a0a81cSdrh SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x 30306a0a81cSdrh UNION ALL SELECT -9223372036854775807) 30406a0a81cSdrh } 30506a0a81cSdrh } {integer} 30606a0a81cSdrh do_test func-8.7 { 30706a0a81cSdrh execsql { 30801859b0bSdrh SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x 30985e9e22bSdrh UNION ALL SELECT -9223372036854775807) 31085e9e22bSdrh } 31101859b0bSdrh } {real} 31206a0a81cSdrh do_test func-8.8 { 31301859b0bSdrh execsql { 31406a0a81cSdrh SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x 31501859b0bSdrh UNION ALL SELECT -9223372036850000000) 31601859b0bSdrh } 31706a0a81cSdrh } {1} 318de3e41e3Sdanielk1977} 319739105c7Sdrh 320a9f9d1c0Sdrh# How do you test the random() function in a meaningful, deterministic way? 321a9f9d1c0Sdrh# 322a9f9d1c0Sdrhdo_test func-9.1 { 323a9f9d1c0Sdrh execsql { 324a9f9d1c0Sdrh SELECT random() is not null; 325a9f9d1c0Sdrh } 326a9f9d1c0Sdrh} {1} 32763cf66f0Sdrhdo_test func-9.2 { 32863cf66f0Sdrh execsql { 32963cf66f0Sdrh SELECT typeof(random()); 33063cf66f0Sdrh } 33163cf66f0Sdrh} {integer} 33263cf66f0Sdrhdo_test func-9.3 { 33363cf66f0Sdrh execsql { 334137c728fSdrh SELECT randomblob(32) is not null; 33563cf66f0Sdrh } 33663cf66f0Sdrh} {1} 33763cf66f0Sdrhdo_test func-9.4 { 33863cf66f0Sdrh execsql { 339137c728fSdrh SELECT typeof(randomblob(32)); 34063cf66f0Sdrh } 341137c728fSdrh} {blob} 34263cf66f0Sdrhdo_test func-9.5 { 34363cf66f0Sdrh execsql { 344137c728fSdrh SELECT length(randomblob(32)), length(randomblob(-5)), 345137c728fSdrh length(randomblob(2000)) 34663cf66f0Sdrh } 347137c728fSdrh} {32 1 2000} 34863cf66f0Sdrh 349137c728fSdrh# The "hex()" function was added in order to be able to render blobs 350137c728fSdrh# generated by randomblob(). So this seems like a good place to test 351137c728fSdrh# hex(). 352137c728fSdrh# 3534152e677Sdanielk1977ifcapable bloblit { 354137c728fSdrh do_test func-9.10 { 355137c728fSdrh execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')} 356137c728fSdrh } {00112233445566778899AABBCCDDEEFF} 3574152e677Sdanielk1977} 358056c8f78Sdrhset encoding [db one {PRAGMA encoding}] 359056c8f78Sdrhif {$encoding=="UTF-16le"} { 360056c8f78Sdrh do_test func-9.11-utf16le { 3611eb2538aSdrh execsql {SELECT hex(replace('abcdefg','ef','12'))} 362056c8f78Sdrh } {6100620063006400310032006700} 363056c8f78Sdrh do_test func-9.12-utf16le { 364709cff33Sdrh execsql {SELECT hex(replace('abcdefg','','12'))} 365709cff33Sdrh } {{}} 366056c8f78Sdrh do_test func-9.13-utf16le { 367056c8f78Sdrh execsql {SELECT hex(replace('aabcdefg','a','aaa'))} 368056c8f78Sdrh } {610061006100610061006100620063006400650066006700} 369056c8f78Sdrh} elseif {$encoding=="UTF-8"} { 370056c8f78Sdrh do_test func-9.11-utf8 { 371056c8f78Sdrh execsql {SELECT hex(replace('abcdefg','ef','12'))} 372056c8f78Sdrh } {61626364313267} 373056c8f78Sdrh do_test func-9.12-utf8 { 374056c8f78Sdrh execsql {SELECT hex(replace('abcdefg','','12'))} 375056c8f78Sdrh } {{}} 376056c8f78Sdrh do_test func-9.13-utf8 { 377709cff33Sdrh execsql {SELECT hex(replace('aabcdefg','a','aaa'))} 378709cff33Sdrh } {616161616161626364656667} 379056c8f78Sdrh} 380bf4133cbSdrh 3816cbe1f1bSdrh# Use the "sqlite_register_test_function" TCL command which is part of 3826cbe1f1bSdrh# the text fixture in order to verify correct operation of some of 3836cbe1f1bSdrh# the user-defined SQL function APIs that are not used by the built-in 3846cbe1f1bSdrh# functions. 3856cbe1f1bSdrh# 386dddca286Sdrhset ::DB [sqlite3_connection_pointer db] 3876cbe1f1bSdrhsqlite_register_test_function $::DB testfunc 3886cbe1f1bSdrhdo_test func-10.1 { 3896cbe1f1bSdrh catchsql { 3906cbe1f1bSdrh SELECT testfunc(NULL,NULL); 3916cbe1f1bSdrh } 3926d88bad4Sdanielk1977} {1 {first argument should be one of: int int64 string double null value}} 3936cbe1f1bSdrhdo_test func-10.2 { 3946cbe1f1bSdrh execsql { 3956cbe1f1bSdrh SELECT testfunc( 3966cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3976cbe1f1bSdrh 'int', 1234 3986cbe1f1bSdrh ); 3996cbe1f1bSdrh } 4006cbe1f1bSdrh} {1234} 4016cbe1f1bSdrhdo_test func-10.3 { 4026cbe1f1bSdrh execsql { 4036cbe1f1bSdrh SELECT testfunc( 4046cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4056cbe1f1bSdrh 'string', NULL 4066cbe1f1bSdrh ); 4076cbe1f1bSdrh } 4086cbe1f1bSdrh} {{}} 4096cbe1f1bSdrhdo_test func-10.4 { 4106cbe1f1bSdrh execsql { 4116cbe1f1bSdrh SELECT testfunc( 4126cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4136cbe1f1bSdrh 'double', 1.234 4146cbe1f1bSdrh ); 4156cbe1f1bSdrh } 4166cbe1f1bSdrh} {1.234} 4176cbe1f1bSdrhdo_test func-10.5 { 4186cbe1f1bSdrh execsql { 4196cbe1f1bSdrh SELECT testfunc( 4206cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4216cbe1f1bSdrh 'int', 1234, 4226cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4236cbe1f1bSdrh 'string', NULL, 4246cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4256cbe1f1bSdrh 'double', 1.234, 4266cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4276cbe1f1bSdrh 'int', 1234, 4286cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4296cbe1f1bSdrh 'string', NULL, 4306cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 4316cbe1f1bSdrh 'double', 1.234 4326cbe1f1bSdrh ); 4336cbe1f1bSdrh } 4346cbe1f1bSdrh} {1.234} 4356cbe1f1bSdrh 436647cb0e1Sdrh# Test the built-in sqlite_version(*) SQL function. 437647cb0e1Sdrh# 438647cb0e1Sdrhdo_test func-11.1 { 439647cb0e1Sdrh execsql { 440647cb0e1Sdrh SELECT sqlite_version(*); 441647cb0e1Sdrh } 442ef4ac8f9Sdrh} [sqlite3 -version] 443647cb0e1Sdrh 444ef4ac8f9Sdrh# Test that destructors passed to sqlite3 by calls to sqlite3_result_text() 4453f6b0874Sdanielk1977# etc. are called. These tests use two special user-defined functions 4463f6b0874Sdanielk1977# (implemented in func.c) only available in test builds. 4473f6b0874Sdanielk1977# 4483f6b0874Sdanielk1977# Function test_destructor() takes one argument and returns a copy of the 4493f6b0874Sdanielk1977# text form of that argument. A destructor is associated with the return 4503f6b0874Sdanielk1977# value. Function test_destructor_count() returns the number of outstanding 4513f6b0874Sdanielk1977# destructor calls for values returned by test_destructor(). 4523f6b0874Sdanielk1977# 453da84ca8dSdrhif {[db eval {PRAGMA encoding}]=="UTF-8"} { 454da84ca8dSdrh do_test func-12.1-utf8 { 455d8123366Sdanielk1977 execsql { 456d8123366Sdanielk1977 SELECT test_destructor('hello world'), test_destructor_count(); 457d8123366Sdanielk1977 } 458d8123366Sdanielk1977 } {{hello world} 1} 459da84ca8dSdrh} else { 4602a5fc4d6Sshane ifcapable {utf16} { 461da84ca8dSdrh do_test func-12.1-utf16 { 462da84ca8dSdrh execsql { 463da84ca8dSdrh SELECT test_destructor16('hello world'), test_destructor_count(); 464da84ca8dSdrh } 465da84ca8dSdrh } {{hello world} 1} 466da84ca8dSdrh } 4672a5fc4d6Sshane} 468d8123366Sdanielk1977do_test func-12.2 { 469d8123366Sdanielk1977 execsql { 470d8123366Sdanielk1977 SELECT test_destructor_count(); 471d8123366Sdanielk1977 } 472d8123366Sdanielk1977} {0} 473d8123366Sdanielk1977do_test func-12.3 { 474d8123366Sdanielk1977 execsql { 4752dcef11bSdrh SELECT test_destructor('hello')||' world' 476d8123366Sdanielk1977 } 4772dcef11bSdrh} {{hello world}} 478d8123366Sdanielk1977do_test func-12.4 { 479d8123366Sdanielk1977 execsql { 480d8123366Sdanielk1977 SELECT test_destructor_count(); 481d8123366Sdanielk1977 } 482d8123366Sdanielk1977} {0} 483d8123366Sdanielk1977do_test func-12.5 { 484d8123366Sdanielk1977 execsql { 485d8123366Sdanielk1977 CREATE TABLE t4(x); 486d8123366Sdanielk1977 INSERT INTO t4 VALUES(test_destructor('hello')); 487d8123366Sdanielk1977 INSERT INTO t4 VALUES(test_destructor('world')); 488d8123366Sdanielk1977 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4; 489d8123366Sdanielk1977 } 490d8123366Sdanielk1977} {hello world} 491d8123366Sdanielk1977do_test func-12.6 { 492d8123366Sdanielk1977 execsql { 493d8123366Sdanielk1977 SELECT test_destructor_count(); 494d8123366Sdanielk1977 } 495d8123366Sdanielk1977} {0} 4963f6b0874Sdanielk1977do_test func-12.7 { 4973f6b0874Sdanielk1977 execsql { 4983f6b0874Sdanielk1977 DROP TABLE t4; 4993f6b0874Sdanielk1977 } 5003f6b0874Sdanielk1977} {} 5013f6b0874Sdanielk1977 502a4e5d58fSdrh 5033f6b0874Sdanielk1977# Test that the auxdata API for scalar functions works. This test uses 5043f6b0874Sdanielk1977# a special user-defined function only available in test builds, 5053f6b0874Sdanielk1977# test_auxdata(). Function test_auxdata() takes any number of arguments. 5063f6b0874Sdanielk1977do_test func-13.1 { 5073f6b0874Sdanielk1977 execsql { 5083f6b0874Sdanielk1977 SELECT test_auxdata('hello world'); 5093f6b0874Sdanielk1977 } 5103f6b0874Sdanielk1977} {0} 511ece80f1eSdanielk1977 5123f6b0874Sdanielk1977do_test func-13.2 { 5133f6b0874Sdanielk1977 execsql { 5143f6b0874Sdanielk1977 CREATE TABLE t4(a, b); 5153f6b0874Sdanielk1977 INSERT INTO t4 VALUES('abc', 'def'); 5163f6b0874Sdanielk1977 INSERT INTO t4 VALUES('ghi', 'jkl'); 5173f6b0874Sdanielk1977 } 5183f6b0874Sdanielk1977} {} 5193f6b0874Sdanielk1977do_test func-13.3 { 5203f6b0874Sdanielk1977 execsql { 5213f6b0874Sdanielk1977 SELECT test_auxdata('hello world') FROM t4; 5223f6b0874Sdanielk1977 } 5233f6b0874Sdanielk1977} {0 1} 5243f6b0874Sdanielk1977do_test func-13.4 { 5253f6b0874Sdanielk1977 execsql { 5263f6b0874Sdanielk1977 SELECT test_auxdata('hello world', 123) FROM t4; 5273f6b0874Sdanielk1977 } 5283f6b0874Sdanielk1977} {{0 0} {1 1}} 5293f6b0874Sdanielk1977do_test func-13.5 { 5303f6b0874Sdanielk1977 execsql { 5313f6b0874Sdanielk1977 SELECT test_auxdata('hello world', a) FROM t4; 5323f6b0874Sdanielk1977 } 5333f6b0874Sdanielk1977} {{0 0} {1 0}} 5343f6b0874Sdanielk1977do_test func-13.6 { 5353f6b0874Sdanielk1977 execsql { 5363f6b0874Sdanielk1977 SELECT test_auxdata('hello'||'world', a) FROM t4; 5373f6b0874Sdanielk1977 } 5383f6b0874Sdanielk1977} {{0 0} {1 0}} 5393f6b0874Sdanielk1977 5403f6b0874Sdanielk1977# Test that auxilary data is preserved between calls for SQL variables. 5413f6b0874Sdanielk1977do_test func-13.7 { 542dddca286Sdrh set DB [sqlite3_connection_pointer db] 5433f6b0874Sdanielk1977 set sql "SELECT test_auxdata( ? , a ) FROM t4;" 5443f6b0874Sdanielk1977 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 54510dfbbb5Sdrh sqlite3_bind_text $STMT 1 hello\000 -1 5463f6b0874Sdanielk1977 set res [list] 5473f6b0874Sdanielk1977 while { "SQLITE_ROW"==[sqlite3_step $STMT] } { 5483f6b0874Sdanielk1977 lappend res [sqlite3_column_text $STMT 0] 5493f6b0874Sdanielk1977 } 5503f6b0874Sdanielk1977 lappend res [sqlite3_finalize $STMT] 5513f6b0874Sdanielk1977} {{0 0} {1 0} SQLITE_OK} 552d8123366Sdanielk1977 553312d6b36Sdanielk1977# Make sure that a function with a very long name is rejected 554312d6b36Sdanielk1977do_test func-14.1 { 555312d6b36Sdanielk1977 catch { 556312d6b36Sdanielk1977 db function [string repeat X 254] {return "hello"} 557312d6b36Sdanielk1977 } 558312d6b36Sdanielk1977} {0} 559312d6b36Sdanielk1977do_test func-14.2 { 560312d6b36Sdanielk1977 catch { 561312d6b36Sdanielk1977 db function [string repeat X 256] {return "hello"} 562312d6b36Sdanielk1977 } 563312d6b36Sdanielk1977} {1} 564312d6b36Sdanielk1977 56501427a62Sdanielk1977do_test func-15.1 { 56600e087b2Sdrh catchsql {select test_error(NULL)} 56790669c1dSdrh} {1 {}} 56800e087b2Sdrhdo_test func-15.2 { 56900e087b2Sdrh catchsql {select test_error('this is the error message')} 57000e087b2Sdrh} {1 {this is the error message}} 57100e087b2Sdrhdo_test func-15.3 { 57200e087b2Sdrh catchsql {select test_error('this is the error message',12)} 57300e087b2Sdrh} {1 {this is the error message}} 57400e087b2Sdrhdo_test func-15.4 { 57500e087b2Sdrh db errorcode 57600e087b2Sdrh} {12} 57701427a62Sdanielk1977 578576ec6b3Sdanielk1977# Test the quote function for BLOB and NULL values. 579576ec6b3Sdanielk1977do_test func-16.1 { 580576ec6b3Sdanielk1977 execsql { 581576ec6b3Sdanielk1977 CREATE TABLE tbl2(a, b); 582576ec6b3Sdanielk1977 } 583576ec6b3Sdanielk1977 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL] 584576ec6b3Sdanielk1977 sqlite3_bind_blob $::STMT 1 abc 3 585576ec6b3Sdanielk1977 sqlite3_step $::STMT 586576ec6b3Sdanielk1977 sqlite3_finalize $::STMT 587576ec6b3Sdanielk1977 execsql { 588576ec6b3Sdanielk1977 SELECT quote(a), quote(b) FROM tbl2; 589576ec6b3Sdanielk1977 } 590576ec6b3Sdanielk1977} {X'616263' NULL} 591576ec6b3Sdanielk1977 5922501eb1dSdrh# Correctly handle function error messages that include %. Ticket #1354 5932501eb1dSdrh# 5942501eb1dSdrhdo_test func-17.1 { 5952501eb1dSdrh proc testfunc1 args {error "Error %d with %s percents %p"} 5962501eb1dSdrh db function testfunc1 ::testfunc1 5972501eb1dSdrh catchsql { 5982501eb1dSdrh SELECT testfunc1(1,2,3); 5992501eb1dSdrh } 6002501eb1dSdrh} {1 {Error %d with %s percents %p}} 6012501eb1dSdrh 6023d1d95e6Sdrh# The SUM function should return integer results when all inputs are integer. 6033d1d95e6Sdrh# 6043d1d95e6Sdrhdo_test func-18.1 { 6053d1d95e6Sdrh execsql { 6063d1d95e6Sdrh CREATE TABLE t5(x); 6073d1d95e6Sdrh INSERT INTO t5 VALUES(1); 6083d1d95e6Sdrh INSERT INTO t5 VALUES(-99); 6093d1d95e6Sdrh INSERT INTO t5 VALUES(10000); 6103d1d95e6Sdrh SELECT sum(x) FROM t5; 6113d1d95e6Sdrh } 6123d1d95e6Sdrh} {9902} 6133d1d95e6Sdrhdo_test func-18.2 { 6143d1d95e6Sdrh execsql { 6153d1d95e6Sdrh INSERT INTO t5 VALUES(0.0); 6163d1d95e6Sdrh SELECT sum(x) FROM t5; 6173d1d95e6Sdrh } 6188a51256cSdrh} {9902.0} 619576ec6b3Sdanielk1977 620c2bd913aSdrh# The sum of nothing is NULL. But the sum of all NULLs is NULL. 6213f219f46Sdrh# 62276c730c1Sdrh# The TOTAL of nothing is 0.0. 62376c730c1Sdrh# 6243f219f46Sdrhdo_test func-18.3 { 6253f219f46Sdrh execsql { 6263f219f46Sdrh DELETE FROM t5; 62776c730c1Sdrh SELECT sum(x), total(x) FROM t5; 6283f219f46Sdrh } 62976c730c1Sdrh} {{} 0.0} 6303f219f46Sdrhdo_test func-18.4 { 6313f219f46Sdrh execsql { 6323f219f46Sdrh INSERT INTO t5 VALUES(NULL); 63376c730c1Sdrh SELECT sum(x), total(x) FROM t5 6343f219f46Sdrh } 63576c730c1Sdrh} {{} 0.0} 6363f219f46Sdrhdo_test func-18.5 { 6373f219f46Sdrh execsql { 6383f219f46Sdrh INSERT INTO t5 VALUES(NULL); 63976c730c1Sdrh SELECT sum(x), total(x) FROM t5 6403f219f46Sdrh } 64176c730c1Sdrh} {{} 0.0} 6423f219f46Sdrhdo_test func-18.6 { 6433f219f46Sdrh execsql { 6443f219f46Sdrh INSERT INTO t5 VALUES(123); 64576c730c1Sdrh SELECT sum(x), total(x) FROM t5 6463f219f46Sdrh } 64776c730c1Sdrh} {123 123.0} 6485708d2deSdrh 6498c08e861Sdrh# Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes 6508c08e861Sdrh# an error. The non-standard TOTAL() function continues to give a helpful 6518c08e861Sdrh# result. 652fc6ad39cSdrh# 653fc6ad39cSdrhdo_test func-18.10 { 654fc6ad39cSdrh execsql { 655fc6ad39cSdrh CREATE TABLE t6(x INTEGER); 656fc6ad39cSdrh INSERT INTO t6 VALUES(1); 657fc6ad39cSdrh INSERT INTO t6 VALUES(1<<62); 658fc6ad39cSdrh SELECT sum(x) - ((1<<62)+1) from t6; 659fc6ad39cSdrh } 660fc6ad39cSdrh} 0 66176c730c1Sdrhdo_test func-18.11 { 66276c730c1Sdrh execsql { 66376c730c1Sdrh SELECT typeof(sum(x)) FROM t6 66476c730c1Sdrh } 66576c730c1Sdrh} integer 66676c730c1Sdrhdo_test func-18.12 { 6678c08e861Sdrh catchsql { 66876c730c1Sdrh INSERT INTO t6 VALUES(1<<62); 66976c730c1Sdrh SELECT sum(x) - ((1<<62)*2.0+1) from t6; 67076c730c1Sdrh } 6718c08e861Sdrh} {1 {integer overflow}} 67276c730c1Sdrhdo_test func-18.13 { 67376c730c1Sdrh execsql { 67476c730c1Sdrh SELECT total(x) - ((1<<62)*2.0+1) FROM t6 67576c730c1Sdrh } 67676c730c1Sdrh} 0.0 6778c08e861Sdrhdo_test func-18.14 { 6788c08e861Sdrh execsql { 6798c08e861Sdrh SELECT sum(-9223372036854775805); 6808c08e861Sdrh } 6818c08e861Sdrh} -9223372036854775805 6824b2688abSdanielk1977 6834b2688abSdanielk1977ifcapable compound&&subquery { 6844b2688abSdanielk1977 6858c08e861Sdrhdo_test func-18.15 { 6868c08e861Sdrh catchsql { 6878c08e861Sdrh SELECT sum(x) FROM 6888c08e861Sdrh (SELECT 9223372036854775807 AS x UNION ALL 6898c08e861Sdrh SELECT 10 AS x); 6908c08e861Sdrh } 6918c08e861Sdrh} {1 {integer overflow}} 6928c08e861Sdrhdo_test func-18.16 { 6938c08e861Sdrh catchsql { 6948c08e861Sdrh SELECT sum(x) FROM 6958c08e861Sdrh (SELECT 9223372036854775807 AS x UNION ALL 6968c08e861Sdrh SELECT -10 AS x); 6978c08e861Sdrh } 6988c08e861Sdrh} {0 9223372036854775797} 6998c08e861Sdrhdo_test func-18.17 { 7008c08e861Sdrh catchsql { 7018c08e861Sdrh SELECT sum(x) FROM 7028c08e861Sdrh (SELECT -9223372036854775807 AS x UNION ALL 7038c08e861Sdrh SELECT 10 AS x); 7048c08e861Sdrh } 7058c08e861Sdrh} {0 -9223372036854775797} 7068c08e861Sdrhdo_test func-18.18 { 7078c08e861Sdrh catchsql { 7088c08e861Sdrh SELECT sum(x) FROM 7098c08e861Sdrh (SELECT -9223372036854775807 AS x UNION ALL 7108c08e861Sdrh SELECT -10 AS x); 7118c08e861Sdrh } 7128c08e861Sdrh} {1 {integer overflow}} 7138c08e861Sdrhdo_test func-18.19 { 7148c08e861Sdrh catchsql { 7158c08e861Sdrh SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x); 7168c08e861Sdrh } 7178c08e861Sdrh} {0 -1} 7188c08e861Sdrhdo_test func-18.20 { 7198c08e861Sdrh catchsql { 7208c08e861Sdrh SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x); 7218c08e861Sdrh } 7228c08e861Sdrh} {0 1} 7238c08e861Sdrhdo_test func-18.21 { 7248c08e861Sdrh catchsql { 7258c08e861Sdrh SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x); 7268c08e861Sdrh } 7278c08e861Sdrh} {0 -1} 7288c08e861Sdrhdo_test func-18.22 { 7298c08e861Sdrh catchsql { 7308c08e861Sdrh SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x); 7318c08e861Sdrh } 7328c08e861Sdrh} {0 1} 73376c730c1Sdrh 7344b2688abSdanielk1977} ;# ifcapable compound&&subquery 7354b2688abSdanielk1977 73652fc849aSdrh# Integer overflow on abs() 73752fc849aSdrh# 73852fc849aSdrhdo_test func-18.31 { 73952fc849aSdrh catchsql { 74052fc849aSdrh SELECT abs(-9223372036854775807); 74152fc849aSdrh } 74252fc849aSdrh} {0 9223372036854775807} 74352fc849aSdrhdo_test func-18.32 { 74452fc849aSdrh catchsql { 74552fc849aSdrh SELECT abs(-9223372036854775807-1); 74652fc849aSdrh } 74752fc849aSdrh} {1 {integer overflow}} 74852fc849aSdrh 7497f375901Sdrh# The MATCH function exists but is only a stub and always throws an error. 7507f375901Sdrh# 7517f375901Sdrhdo_test func-19.1 { 7527f375901Sdrh execsql { 7537f375901Sdrh SELECT match(a,b) FROM t1 WHERE 0; 7547f375901Sdrh } 7557f375901Sdrh} {} 7567f375901Sdrhdo_test func-19.2 { 7577f375901Sdrh catchsql { 7587f375901Sdrh SELECT 'abc' MATCH 'xyz'; 7597f375901Sdrh } 760b7481e70Sdrh} {1 {unable to use function MATCH in the requested context}} 7617f375901Sdrhdo_test func-19.3 { 7627f375901Sdrh catchsql { 7637f375901Sdrh SELECT 'abc' NOT MATCH 'xyz'; 7647f375901Sdrh } 765b7481e70Sdrh} {1 {unable to use function MATCH in the requested context}} 7667f375901Sdrhdo_test func-19.4 { 7677f375901Sdrh catchsql { 7687f375901Sdrh SELECT match(1,2,3); 7697f375901Sdrh } 7707f375901Sdrh} {1 {wrong number of arguments to function match()}} 77176c730c1Sdrh 772bdf67e0eSdrh# Soundex tests. 773bdf67e0eSdrh# 774bdf67e0eSdrhif {![catch {db eval {SELECT soundex('hello')}}]} { 775bdf67e0eSdrh set i 0 776bdf67e0eSdrh foreach {name sdx} { 777bdf67e0eSdrh euler E460 778bdf67e0eSdrh EULER E460 779bdf67e0eSdrh Euler E460 780bdf67e0eSdrh ellery E460 781bdf67e0eSdrh gauss G200 782bdf67e0eSdrh ghosh G200 783bdf67e0eSdrh hilbert H416 784bdf67e0eSdrh Heilbronn H416 785bdf67e0eSdrh knuth K530 786bdf67e0eSdrh kant K530 787bdf67e0eSdrh Lloyd L300 788bdf67e0eSdrh LADD L300 789bdf67e0eSdrh Lukasiewicz L222 790bdf67e0eSdrh Lissajous L222 791bdf67e0eSdrh A A000 792bdf67e0eSdrh 12345 ?000 793bdf67e0eSdrh } { 794bdf67e0eSdrh incr i 795bdf67e0eSdrh do_test func-20.$i { 796bdf67e0eSdrh execsql {SELECT soundex($name)} 797bdf67e0eSdrh } $sdx 798bdf67e0eSdrh } 799bdf67e0eSdrh} 800bdf67e0eSdrh 80126b6d90dSdrh# Tests of the REPLACE function. 80226b6d90dSdrh# 80326b6d90dSdrhdo_test func-21.1 { 80426b6d90dSdrh catchsql { 80526b6d90dSdrh SELECT replace(1,2); 80626b6d90dSdrh } 80726b6d90dSdrh} {1 {wrong number of arguments to function replace()}} 80826b6d90dSdrhdo_test func-21.2 { 80926b6d90dSdrh catchsql { 81026b6d90dSdrh SELECT replace(1,2,3,4); 81126b6d90dSdrh } 81226b6d90dSdrh} {1 {wrong number of arguments to function replace()}} 81326b6d90dSdrhdo_test func-21.3 { 81426b6d90dSdrh execsql { 81526b6d90dSdrh SELECT typeof(replace("This is the main test string", NULL, "ALT")); 81626b6d90dSdrh } 81726b6d90dSdrh} {null} 81826b6d90dSdrhdo_test func-21.4 { 81926b6d90dSdrh execsql { 82026b6d90dSdrh SELECT typeof(replace(NULL, "main", "ALT")); 82126b6d90dSdrh } 82226b6d90dSdrh} {null} 82326b6d90dSdrhdo_test func-21.5 { 82426b6d90dSdrh execsql { 82526b6d90dSdrh SELECT typeof(replace("This is the main test string", "main", NULL)); 82626b6d90dSdrh } 82726b6d90dSdrh} {null} 82826b6d90dSdrhdo_test func-21.6 { 82926b6d90dSdrh execsql { 83026b6d90dSdrh SELECT replace("This is the main test string", "main", "ALT"); 83126b6d90dSdrh } 83226b6d90dSdrh} {{This is the ALT test string}} 83326b6d90dSdrhdo_test func-21.7 { 83426b6d90dSdrh execsql { 83526b6d90dSdrh SELECT replace("This is the main test string", "main", "larger-main"); 83626b6d90dSdrh } 83726b6d90dSdrh} {{This is the larger-main test string}} 83826b6d90dSdrhdo_test func-21.8 { 83926b6d90dSdrh execsql { 84026b6d90dSdrh SELECT replace("aaaaaaa", "a", "0123456789"); 84126b6d90dSdrh } 84226b6d90dSdrh} {0123456789012345678901234567890123456789012345678901234567890123456789} 84326b6d90dSdrh 8444152e677Sdanielk1977ifcapable tclvar { 84517374e8fSdanielk1977 do_test func-21.9 { 84617374e8fSdanielk1977 # Attempt to exploit a buffer-overflow that at one time existed 84717374e8fSdanielk1977 # in the REPLACE function. 84817374e8fSdanielk1977 set ::str "[string repeat A 29998]CC[string repeat A 35537]" 84917374e8fSdanielk1977 set ::rep [string repeat B 65536] 85017374e8fSdanielk1977 execsql { 85117374e8fSdanielk1977 SELECT LENGTH(REPLACE($::str, 'C', $::rep)); 85217374e8fSdanielk1977 } 85317374e8fSdanielk1977 } [expr 29998 + 2*65536 + 35537] 8544152e677Sdanielk1977} 85517374e8fSdanielk1977 856309b3386Sdrh# Tests for the TRIM, LTRIM and RTRIM functions. 857309b3386Sdrh# 858309b3386Sdrhdo_test func-22.1 { 859309b3386Sdrh catchsql {SELECT trim(1,2,3)} 860309b3386Sdrh} {1 {wrong number of arguments to function trim()}} 861309b3386Sdrhdo_test func-22.2 { 862309b3386Sdrh catchsql {SELECT ltrim(1,2,3)} 863309b3386Sdrh} {1 {wrong number of arguments to function ltrim()}} 864309b3386Sdrhdo_test func-22.3 { 865309b3386Sdrh catchsql {SELECT rtrim(1,2,3)} 866309b3386Sdrh} {1 {wrong number of arguments to function rtrim()}} 867309b3386Sdrhdo_test func-22.4 { 868309b3386Sdrh execsql {SELECT trim(' hi ');} 869309b3386Sdrh} {hi} 870309b3386Sdrhdo_test func-22.5 { 871309b3386Sdrh execsql {SELECT ltrim(' hi ');} 872309b3386Sdrh} {{hi }} 873309b3386Sdrhdo_test func-22.6 { 874309b3386Sdrh execsql {SELECT rtrim(' hi ');} 875309b3386Sdrh} {{ hi}} 876309b3386Sdrhdo_test func-22.7 { 877309b3386Sdrh execsql {SELECT trim(' hi ','xyz');} 878309b3386Sdrh} {{ hi }} 879309b3386Sdrhdo_test func-22.8 { 880309b3386Sdrh execsql {SELECT ltrim(' hi ','xyz');} 881309b3386Sdrh} {{ hi }} 882309b3386Sdrhdo_test func-22.9 { 883309b3386Sdrh execsql {SELECT rtrim(' hi ','xyz');} 884309b3386Sdrh} {{ hi }} 885309b3386Sdrhdo_test func-22.10 { 886309b3386Sdrh execsql {SELECT trim('xyxzy hi zzzy','xyz');} 887309b3386Sdrh} {{ hi }} 888309b3386Sdrhdo_test func-22.11 { 889309b3386Sdrh execsql {SELECT ltrim('xyxzy hi zzzy','xyz');} 890309b3386Sdrh} {{ hi zzzy}} 891309b3386Sdrhdo_test func-22.12 { 892309b3386Sdrh execsql {SELECT rtrim('xyxzy hi zzzy','xyz');} 893309b3386Sdrh} {{xyxzy hi }} 894309b3386Sdrhdo_test func-22.13 { 895309b3386Sdrh execsql {SELECT trim(' hi ','');} 896309b3386Sdrh} {{ hi }} 8974e05c83bSdrhif {[db one {PRAGMA encoding}]=="UTF-8"} { 898d1e3a616Sdrh do_test func-22.14 { 8997a928d75Sdrh execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))} 9007a928d75Sdrh } {F48FBFBF6869} 901d1e3a616Sdrh do_test func-22.15 { 9027a928d75Sdrh execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61', 9037a928d75Sdrh x'6162e1bfbfc280f48fbfbf'))} 904d1e3a616Sdrh } {6869} 905d1e3a616Sdrh do_test func-22.16 { 906d1e3a616Sdrh execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));} 907d1e3a616Sdrh } {CEB2CEB3} 9084e05c83bSdrh} 909309b3386Sdrhdo_test func-22.20 { 910309b3386Sdrh execsql {SELECT typeof(trim(NULL));} 911309b3386Sdrh} {null} 912309b3386Sdrhdo_test func-22.21 { 913309b3386Sdrh execsql {SELECT typeof(trim(NULL,'xyz'));} 914309b3386Sdrh} {null} 915309b3386Sdrhdo_test func-22.22 { 916309b3386Sdrh execsql {SELECT typeof(trim('hello',NULL));} 917309b3386Sdrh} {null} 91826b6d90dSdrh 919fa18beceSdanielk1977# This is to test the deprecated sqlite3_aggregate_count() API. 920fa18beceSdanielk1977# 921eec556d3Sshaneifcapable deprecated { 922fa18beceSdanielk1977 do_test func-23.1 { 923fa18beceSdanielk1977 sqlite3_create_aggregate db 924fa18beceSdanielk1977 execsql { 925fa18beceSdanielk1977 SELECT legacy_count() FROM t6; 926fa18beceSdanielk1977 } 927fa18beceSdanielk1977 } {3} 928eec556d3Sshane} 929fa18beceSdanielk1977 930ade86483Sdrh# The group_concat() function. 931ade86483Sdrh# 932ade86483Sdrhdo_test func-24.1 { 933ade86483Sdrh execsql { 934ade86483Sdrh SELECT group_concat(t1) FROM tbl1 935ade86483Sdrh } 936ade86483Sdrh} {this,program,is,free,software} 937ade86483Sdrhdo_test func-24.2 { 938ade86483Sdrh execsql { 939ade86483Sdrh SELECT group_concat(t1,' ') FROM tbl1 940ade86483Sdrh } 941ade86483Sdrh} {{this program is free software}} 942ade86483Sdrhdo_test func-24.3 { 943ade86483Sdrh execsql { 944ade86483Sdrh SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1 945ade86483Sdrh } 946ade86483Sdrh} {{this 2 program 3 is 4 free 5 software}} 947ade86483Sdrhdo_test func-24.4 { 948ade86483Sdrh execsql { 949ade86483Sdrh SELECT group_concat(NULL,t1) FROM tbl1 950ade86483Sdrh } 951ade86483Sdrh} {{}} 952ade86483Sdrhdo_test func-24.5 { 953ade86483Sdrh execsql { 954ade86483Sdrh SELECT group_concat(t1,NULL) FROM tbl1 955ade86483Sdrh } 956ade86483Sdrh} {thisprogramisfreesoftware} 9572dca8680Sdrhdo_test func-24.6 { 9582dca8680Sdrh execsql { 9592dca8680Sdrh SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 9602dca8680Sdrh } 9612dca8680Sdrh} {BEGIN-this,program,is,free,software} 9623780b5deSdrhunset -nocomplain midargs 963a2baf3a2Sdrhset midargs {} 9643780b5deSdrhunset -nocomplain midres 965a2baf3a2Sdrhset midres {} 9663780b5deSdrhunset -nocomplain result 967a2baf3a2Sdrhfor {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]-1} {incr i} { 968a2baf3a2Sdrh append midargs ,'/$i' 969a2baf3a2Sdrh append midres /$i 970a2baf3a2Sdrh set result \ 971a2baf3a2Sdrh "this$midres:program$midres:is$midres:free$midres:software$midres" 972a2baf3a2Sdrh set sql "SELECT group_concat(t1$midargs,':') FROM tbl1" 973a2baf3a2Sdrh do_test func-24.7.$i { 974a2baf3a2Sdrh db eval $::sql 975a2baf3a2Sdrh } $result 976a2baf3a2Sdrh} 977ade86483Sdrh 978191b54cbSdrh# Use the test_isolation function to make sure that type conversions 979191b54cbSdrh# on function arguments do not effect subsequent arguments. 980191b54cbSdrh# 981191b54cbSdrhdo_test func-25.1 { 982191b54cbSdrh execsql {SELECT test_isolation(t1,t1) FROM tbl1} 983191b54cbSdrh} {this program is free software} 984191b54cbSdrh 98524b58dd7Sdrh# Try to misuse the sqlite3_create_function() interface. Verify that 98624b58dd7Sdrh# errors are returned. 98724b58dd7Sdrh# 98824b58dd7Sdrhdo_test func-26.1 { 98924b58dd7Sdrh abuse_create_function db 99024b58dd7Sdrh} {} 99124b58dd7Sdrh 99224b58dd7Sdrh# The previous test (func-26.1) registered a function with a very long 99324b58dd7Sdrh# function name that takes many arguments and always returns NULL. Verify 99424b58dd7Sdrh# that this function works correctly. 99524b58dd7Sdrh# 99624b58dd7Sdrhdo_test func-26.2 { 99724b58dd7Sdrh set a {} 99824b58dd7Sdrh for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} { 99924b58dd7Sdrh lappend a $i 100024b58dd7Sdrh } 100124b58dd7Sdrh db eval " 100224b58dd7Sdrh 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 ,]); 100324b58dd7Sdrh " 100424b58dd7Sdrh} {{}} 100524b58dd7Sdrhdo_test func-26.3 { 100624b58dd7Sdrh set a {} 100724b58dd7Sdrh for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} { 100824b58dd7Sdrh lappend a $i 100924b58dd7Sdrh } 101024b58dd7Sdrh catchsql " 101124b58dd7Sdrh 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 ,]); 101224b58dd7Sdrh " 101324b58dd7Sdrh} {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}} 101424b58dd7Sdrhdo_test func-26.4 { 101524b58dd7Sdrh set a {} 101624b58dd7Sdrh for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} { 101724b58dd7Sdrh lappend a $i 101824b58dd7Sdrh } 101924b58dd7Sdrh catchsql " 102024b58dd7Sdrh 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 ,]); 102124b58dd7Sdrh " 102224b58dd7Sdrh} {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()}} 102324b58dd7Sdrhdo_test func-26.5 { 102424b58dd7Sdrh catchsql " 102524b58dd7Sdrh 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); 102624b58dd7Sdrh " 102724b58dd7Sdrh} {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}} 102824b58dd7Sdrhdo_test func-26.6 { 102924b58dd7Sdrh catchsql " 103024b58dd7Sdrh 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); 103124b58dd7Sdrh " 103224b58dd7Sdrh} {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}} 103324b58dd7Sdrh 1034*dfbc3a8aSdrhdo_test func-27.1 { 1035*dfbc3a8aSdrh catchsql {SELECT coalesce()} 1036*dfbc3a8aSdrh} {1 {wrong number of arguments to function coalesce()}} 1037*dfbc3a8aSdrhdo_test func-27.2 { 1038*dfbc3a8aSdrh catchsql {SELECT coalesce(1)} 1039*dfbc3a8aSdrh} {1 {wrong number of arguments to function coalesce()}} 1040*dfbc3a8aSdrhdo_test func-27.3 { 1041*dfbc3a8aSdrh catchsql {SELECT coalesce(1,2)} 1042*dfbc3a8aSdrh} {0 1} 1043*dfbc3a8aSdrh 10445708d2deSdrhfinish_test 1045