1*c5c4113dSnw141292 2*c5c4113dSnw141292#pragma ident "%Z%%M% %I% %E% SMI" 3*c5c4113dSnw141292 4*c5c4113dSnw141292# 2001 September 15 5*c5c4113dSnw141292# 6*c5c4113dSnw141292# The author disclaims copyright to this source code. In place of 7*c5c4113dSnw141292# a legal notice, here is a blessing: 8*c5c4113dSnw141292# 9*c5c4113dSnw141292# May you do good and not evil. 10*c5c4113dSnw141292# May you find forgiveness for yourself and forgive others. 11*c5c4113dSnw141292# May you share freely, never taking more than you give. 12*c5c4113dSnw141292# 13*c5c4113dSnw141292#*********************************************************************** 14*c5c4113dSnw141292# This file implements regression tests for SQLite library. The 15*c5c4113dSnw141292# focus of this file is testing built-in functions. 16*c5c4113dSnw141292# 17*c5c4113dSnw141292# $Id: func.test,v 1.16.2.2 2004/07/18 21:14:05 drh Exp $ 18*c5c4113dSnw141292 19*c5c4113dSnw141292set testdir [file dirname $argv0] 20*c5c4113dSnw141292source $testdir/tester.tcl 21*c5c4113dSnw141292 22*c5c4113dSnw141292# Create a table to work with. 23*c5c4113dSnw141292# 24*c5c4113dSnw141292do_test func-0.0 { 25*c5c4113dSnw141292 execsql {CREATE TABLE tbl1(t1 text)} 26*c5c4113dSnw141292 foreach word {this program is free software} { 27*c5c4113dSnw141292 execsql "INSERT INTO tbl1 VALUES('$word')" 28*c5c4113dSnw141292 } 29*c5c4113dSnw141292 execsql {SELECT t1 FROM tbl1 ORDER BY t1} 30*c5c4113dSnw141292} {free is program software this} 31*c5c4113dSnw141292do_test func-0.1 { 32*c5c4113dSnw141292 execsql { 33*c5c4113dSnw141292 CREATE TABLE t2(a); 34*c5c4113dSnw141292 INSERT INTO t2 VALUES(1); 35*c5c4113dSnw141292 INSERT INTO t2 VALUES(NULL); 36*c5c4113dSnw141292 INSERT INTO t2 VALUES(345); 37*c5c4113dSnw141292 INSERT INTO t2 VALUES(NULL); 38*c5c4113dSnw141292 INSERT INTO t2 VALUES(67890); 39*c5c4113dSnw141292 SELECT * FROM t2; 40*c5c4113dSnw141292 } 41*c5c4113dSnw141292} {1 {} 345 {} 67890} 42*c5c4113dSnw141292 43*c5c4113dSnw141292# Check out the length() function 44*c5c4113dSnw141292# 45*c5c4113dSnw141292do_test func-1.0 { 46*c5c4113dSnw141292 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 47*c5c4113dSnw141292} {4 2 7 8 4} 48*c5c4113dSnw141292do_test func-1.1 { 49*c5c4113dSnw141292 set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg] 50*c5c4113dSnw141292 lappend r $msg 51*c5c4113dSnw141292} {1 {wrong number of arguments to function length()}} 52*c5c4113dSnw141292do_test func-1.2 { 53*c5c4113dSnw141292 set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg] 54*c5c4113dSnw141292 lappend r $msg 55*c5c4113dSnw141292} {1 {wrong number of arguments to function length()}} 56*c5c4113dSnw141292do_test func-1.3 { 57*c5c4113dSnw141292 execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1) 58*c5c4113dSnw141292 ORDER BY length(t1)} 59*c5c4113dSnw141292} {2 1 4 2 7 1 8 1} 60*c5c4113dSnw141292do_test func-1.4 { 61*c5c4113dSnw141292 execsql {SELECT coalesce(length(a),-1) FROM t2} 62*c5c4113dSnw141292} {1 -1 3 -1 5} 63*c5c4113dSnw141292 64*c5c4113dSnw141292# Check out the substr() function 65*c5c4113dSnw141292# 66*c5c4113dSnw141292do_test func-2.0 { 67*c5c4113dSnw141292 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 68*c5c4113dSnw141292} {fr is pr so th} 69*c5c4113dSnw141292do_test func-2.1 { 70*c5c4113dSnw141292 execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1} 71*c5c4113dSnw141292} {r s r o h} 72*c5c4113dSnw141292do_test func-2.2 { 73*c5c4113dSnw141292 execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1} 74*c5c4113dSnw141292} {ee {} ogr ftw is} 75*c5c4113dSnw141292do_test func-2.3 { 76*c5c4113dSnw141292 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 77*c5c4113dSnw141292} {e s m e s} 78*c5c4113dSnw141292do_test func-2.4 { 79*c5c4113dSnw141292 execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1} 80*c5c4113dSnw141292} {e s m e s} 81*c5c4113dSnw141292do_test func-2.5 { 82*c5c4113dSnw141292 execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1} 83*c5c4113dSnw141292} {e i a r i} 84*c5c4113dSnw141292do_test func-2.6 { 85*c5c4113dSnw141292 execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1} 86*c5c4113dSnw141292} {ee is am re is} 87*c5c4113dSnw141292do_test func-2.7 { 88*c5c4113dSnw141292 execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1} 89*c5c4113dSnw141292} {fr {} gr wa th} 90*c5c4113dSnw141292do_test func-2.8 { 91*c5c4113dSnw141292 execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)} 92*c5c4113dSnw141292} {this software free program is} 93*c5c4113dSnw141292do_test func-2.9 { 94*c5c4113dSnw141292 execsql {SELECT substr(a,1,1) FROM t2} 95*c5c4113dSnw141292} {1 {} 3 {} 6} 96*c5c4113dSnw141292do_test func-2.10 { 97*c5c4113dSnw141292 execsql {SELECT substr(a,2,2) FROM t2} 98*c5c4113dSnw141292} {{} {} 45 {} 78} 99*c5c4113dSnw141292 100*c5c4113dSnw141292# Only do the following tests if TCL has UTF-8 capabilities and 101*c5c4113dSnw141292# the UTF-8 encoding is turned on in the SQLite library. 102*c5c4113dSnw141292# 103*c5c4113dSnw141292if {[sqlite -encoding]=="UTF-8" && "\u1234"!="u1234"} { 104*c5c4113dSnw141292 105*c5c4113dSnw141292# Put some UTF-8 characters in the database 106*c5c4113dSnw141292# 107*c5c4113dSnw141292do_test func-3.0 { 108*c5c4113dSnw141292 execsql {DELETE FROM tbl1} 109*c5c4113dSnw141292 foreach word "contains UTF-8 characters hi\u1234ho" { 110*c5c4113dSnw141292 execsql "INSERT INTO tbl1 VALUES('$word')" 111*c5c4113dSnw141292 } 112*c5c4113dSnw141292 execsql {SELECT t1 FROM tbl1 ORDER BY t1} 113*c5c4113dSnw141292} "UTF-8 characters contains hi\u1234ho" 114*c5c4113dSnw141292do_test func-3.1 { 115*c5c4113dSnw141292 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} 116*c5c4113dSnw141292} {5 10 8 5} 117*c5c4113dSnw141292do_test func-3.2 { 118*c5c4113dSnw141292 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} 119*c5c4113dSnw141292} {UT ch co hi} 120*c5c4113dSnw141292do_test func-3.3 { 121*c5c4113dSnw141292 execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1} 122*c5c4113dSnw141292} "UTF cha con hi\u1234" 123*c5c4113dSnw141292do_test func-3.4 { 124*c5c4113dSnw141292 execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1} 125*c5c4113dSnw141292} "TF ha on i\u1234" 126*c5c4113dSnw141292do_test func-3.5 { 127*c5c4113dSnw141292 execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1} 128*c5c4113dSnw141292} "TF- har ont i\u1234h" 129*c5c4113dSnw141292do_test func-3.6 { 130*c5c4113dSnw141292 execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1} 131*c5c4113dSnw141292} "F- ar nt \u1234h" 132*c5c4113dSnw141292do_test func-3.7 { 133*c5c4113dSnw141292 execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1} 134*c5c4113dSnw141292} "-8 ra ta ho" 135*c5c4113dSnw141292do_test func-3.8 { 136*c5c4113dSnw141292 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1} 137*c5c4113dSnw141292} "8 s s o" 138*c5c4113dSnw141292do_test func-3.9 { 139*c5c4113dSnw141292 execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1} 140*c5c4113dSnw141292} "F- er in \u1234h" 141*c5c4113dSnw141292do_test func-3.10 { 142*c5c4113dSnw141292 execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1} 143*c5c4113dSnw141292} "TF- ter ain i\u1234h" 144*c5c4113dSnw141292do_test func-3.99 { 145*c5c4113dSnw141292 execsql {DELETE FROM tbl1} 146*c5c4113dSnw141292 foreach word {this program is free software} { 147*c5c4113dSnw141292 execsql "INSERT INTO tbl1 VALUES('$word')" 148*c5c4113dSnw141292 } 149*c5c4113dSnw141292 execsql {SELECT t1 FROM tbl1} 150*c5c4113dSnw141292} {this program is free software} 151*c5c4113dSnw141292 152*c5c4113dSnw141292} ;# End [sqlite -encoding]==UTF-8 and \u1234!=u1234 153*c5c4113dSnw141292 154*c5c4113dSnw141292# Test the abs() and round() functions. 155*c5c4113dSnw141292# 156*c5c4113dSnw141292do_test func-4.1 { 157*c5c4113dSnw141292 execsql { 158*c5c4113dSnw141292 CREATE TABLE t1(a,b,c); 159*c5c4113dSnw141292 INSERT INTO t1 VALUES(1,2,3); 160*c5c4113dSnw141292 INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890); 161*c5c4113dSnw141292 INSERT INTO t1 VALUES(3,-2,-5); 162*c5c4113dSnw141292 } 163*c5c4113dSnw141292 catchsql {SELECT abs(a,b) FROM t1} 164*c5c4113dSnw141292} {1 {wrong number of arguments to function abs()}} 165*c5c4113dSnw141292do_test func-4.2 { 166*c5c4113dSnw141292 catchsql {SELECT abs() FROM t1} 167*c5c4113dSnw141292} {1 {wrong number of arguments to function abs()}} 168*c5c4113dSnw141292do_test func-4.3 { 169*c5c4113dSnw141292 catchsql {SELECT abs(b) FROM t1 ORDER BY a} 170*c5c4113dSnw141292} {0 {2 1.2345678901234 2}} 171*c5c4113dSnw141292do_test func-4.4 { 172*c5c4113dSnw141292 catchsql {SELECT abs(c) FROM t1 ORDER BY a} 173*c5c4113dSnw141292} {0 {3 12345.67890 5}} 174*c5c4113dSnw141292do_test func-4.4.1 { 175*c5c4113dSnw141292 execsql {SELECT abs(a) FROM t2} 176*c5c4113dSnw141292} {1 {} 345 {} 67890} 177*c5c4113dSnw141292do_test func-4.4.2 { 178*c5c4113dSnw141292 execsql {SELECT abs(t1) FROM tbl1} 179*c5c4113dSnw141292} {this program is free software} 180*c5c4113dSnw141292 181*c5c4113dSnw141292do_test func-4.5 { 182*c5c4113dSnw141292 catchsql {SELECT round(a,b,c) FROM t1} 183*c5c4113dSnw141292} {1 {wrong number of arguments to function round()}} 184*c5c4113dSnw141292do_test func-4.6 { 185*c5c4113dSnw141292 catchsql {SELECT round(b,2) FROM t1 ORDER BY b} 186*c5c4113dSnw141292} {0 {-2.00 1.23 2.00}} 187*c5c4113dSnw141292do_test func-4.7 { 188*c5c4113dSnw141292 catchsql {SELECT round(b,0) FROM t1 ORDER BY a} 189*c5c4113dSnw141292} {0 {2 1 -2}} 190*c5c4113dSnw141292do_test func-4.8 { 191*c5c4113dSnw141292 catchsql {SELECT round(c) FROM t1 ORDER BY a} 192*c5c4113dSnw141292} {0 {3 -12346 -5}} 193*c5c4113dSnw141292do_test func-4.9 { 194*c5c4113dSnw141292 catchsql {SELECT round(c,a) FROM t1 ORDER BY a} 195*c5c4113dSnw141292} {0 {3.0 -12345.68 -5.000}} 196*c5c4113dSnw141292do_test func-4.10 { 197*c5c4113dSnw141292 catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a} 198*c5c4113dSnw141292} {0 {x3.0y x-12345.68y x-5.000y}} 199*c5c4113dSnw141292do_test func-4.11 { 200*c5c4113dSnw141292 catchsql {SELECT round() FROM t1 ORDER BY a} 201*c5c4113dSnw141292} {1 {wrong number of arguments to function round()}} 202*c5c4113dSnw141292do_test func-4.12 { 203*c5c4113dSnw141292 execsql {SELECT coalesce(round(a,2),'nil') FROM t2} 204*c5c4113dSnw141292} {1.00 nil 345.00 nil 67890.00} 205*c5c4113dSnw141292do_test func-4.13 { 206*c5c4113dSnw141292 execsql {SELECT round(t1,2) FROM tbl1} 207*c5c4113dSnw141292} {0.00 0.00 0.00 0.00 0.00} 208*c5c4113dSnw141292 209*c5c4113dSnw141292# Test the upper() and lower() functions 210*c5c4113dSnw141292# 211*c5c4113dSnw141292do_test func-5.1 { 212*c5c4113dSnw141292 execsql {SELECT upper(t1) FROM tbl1} 213*c5c4113dSnw141292} {THIS PROGRAM IS FREE SOFTWARE} 214*c5c4113dSnw141292do_test func-5.2 { 215*c5c4113dSnw141292 execsql {SELECT lower(upper(t1)) FROM tbl1} 216*c5c4113dSnw141292} {this program is free software} 217*c5c4113dSnw141292do_test func-5.3 { 218*c5c4113dSnw141292 execsql {SELECT upper(a), lower(a) FROM t2} 219*c5c4113dSnw141292} {1 1 {} {} 345 345 {} {} 67890 67890} 220*c5c4113dSnw141292do_test func-5.4 { 221*c5c4113dSnw141292 catchsql {SELECT upper(a,5) FROM t2} 222*c5c4113dSnw141292} {1 {wrong number of arguments to function upper()}} 223*c5c4113dSnw141292do_test func-5.5 { 224*c5c4113dSnw141292 catchsql {SELECT upper(*) FROM t2} 225*c5c4113dSnw141292} {1 {wrong number of arguments to function upper()}} 226*c5c4113dSnw141292 227*c5c4113dSnw141292# Test the coalesce() and nullif() functions 228*c5c4113dSnw141292# 229*c5c4113dSnw141292do_test func-6.1 { 230*c5c4113dSnw141292 execsql {SELECT coalesce(a,'xyz') FROM t2} 231*c5c4113dSnw141292} {1 xyz 345 xyz 67890} 232*c5c4113dSnw141292do_test func-6.2 { 233*c5c4113dSnw141292 execsql {SELECT coalesce(upper(a),'nil') FROM t2} 234*c5c4113dSnw141292} {1 nil 345 nil 67890} 235*c5c4113dSnw141292do_test func-6.3 { 236*c5c4113dSnw141292 execsql {SELECT coalesce(nullif(1,1),'nil')} 237*c5c4113dSnw141292} {nil} 238*c5c4113dSnw141292do_test func-6.4 { 239*c5c4113dSnw141292 execsql {SELECT coalesce(nullif(1,2),'nil')} 240*c5c4113dSnw141292} {1} 241*c5c4113dSnw141292do_test func-6.5 { 242*c5c4113dSnw141292 execsql {SELECT coalesce(nullif(1,NULL),'nil')} 243*c5c4113dSnw141292} {1} 244*c5c4113dSnw141292 245*c5c4113dSnw141292 246*c5c4113dSnw141292# Test the last_insert_rowid() function 247*c5c4113dSnw141292# 248*c5c4113dSnw141292do_test func-7.1 { 249*c5c4113dSnw141292 execsql {SELECT last_insert_rowid()} 250*c5c4113dSnw141292} [db last_insert_rowid] 251*c5c4113dSnw141292 252*c5c4113dSnw141292# Tests for aggregate functions and how they handle NULLs. 253*c5c4113dSnw141292# 254*c5c4113dSnw141292do_test func-8.1 { 255*c5c4113dSnw141292 execsql { 256*c5c4113dSnw141292 SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2; 257*c5c4113dSnw141292 } 258*c5c4113dSnw141292} {68236 3 22745.33 1 67890 5} 259*c5c4113dSnw141292do_test func-8.2 { 260*c5c4113dSnw141292 execsql { 261*c5c4113dSnw141292 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; 262*c5c4113dSnw141292 } 263*c5c4113dSnw141292} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 264*c5c4113dSnw141292do_test func-8.3 { 265*c5c4113dSnw141292 execsql { 266*c5c4113dSnw141292 CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 267*c5c4113dSnw141292 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 268*c5c4113dSnw141292 } 269*c5c4113dSnw141292} {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 270*c5c4113dSnw141292do_test func-8.4 { 271*c5c4113dSnw141292 execsql { 272*c5c4113dSnw141292 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 273*c5c4113dSnw141292 } 274*c5c4113dSnw141292} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 275*c5c4113dSnw141292 276*c5c4113dSnw141292# How do you test the random() function in a meaningful, deterministic way? 277*c5c4113dSnw141292# 278*c5c4113dSnw141292do_test func-9.1 { 279*c5c4113dSnw141292 execsql { 280*c5c4113dSnw141292 SELECT random() is not null; 281*c5c4113dSnw141292 } 282*c5c4113dSnw141292} {1} 283*c5c4113dSnw141292 284*c5c4113dSnw141292# Use the "sqlite_register_test_function" TCL command which is part of 285*c5c4113dSnw141292# the text fixture in order to verify correct operation of some of 286*c5c4113dSnw141292# the user-defined SQL function APIs that are not used by the built-in 287*c5c4113dSnw141292# functions. 288*c5c4113dSnw141292# 289*c5c4113dSnw141292db close 290*c5c4113dSnw141292set ::DB [sqlite db test.db] 291*c5c4113dSnw141292sqlite_register_test_function $::DB testfunc 292*c5c4113dSnw141292do_test func-10.1 { 293*c5c4113dSnw141292 catchsql { 294*c5c4113dSnw141292 SELECT testfunc(NULL,NULL); 295*c5c4113dSnw141292 } 296*c5c4113dSnw141292} {1 {first argument to test function may not be NULL}} 297*c5c4113dSnw141292do_test func-10.2 { 298*c5c4113dSnw141292 execsql { 299*c5c4113dSnw141292 SELECT testfunc( 300*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 301*c5c4113dSnw141292 'int', 1234 302*c5c4113dSnw141292 ); 303*c5c4113dSnw141292 } 304*c5c4113dSnw141292} {1234} 305*c5c4113dSnw141292do_test func-10.3 { 306*c5c4113dSnw141292 execsql { 307*c5c4113dSnw141292 SELECT testfunc( 308*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 309*c5c4113dSnw141292 'string', NULL 310*c5c4113dSnw141292 ); 311*c5c4113dSnw141292 } 312*c5c4113dSnw141292} {{}} 313*c5c4113dSnw141292do_test func-10.4 { 314*c5c4113dSnw141292 execsql { 315*c5c4113dSnw141292 SELECT testfunc( 316*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 317*c5c4113dSnw141292 'double', 1.234 318*c5c4113dSnw141292 ); 319*c5c4113dSnw141292 } 320*c5c4113dSnw141292} {1.234} 321*c5c4113dSnw141292do_test func-10.5 { 322*c5c4113dSnw141292 execsql { 323*c5c4113dSnw141292 SELECT testfunc( 324*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 325*c5c4113dSnw141292 'int', 1234, 326*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 327*c5c4113dSnw141292 'string', NULL, 328*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 329*c5c4113dSnw141292 'double', 1.234, 330*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 331*c5c4113dSnw141292 'int', 1234, 332*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 333*c5c4113dSnw141292 'string', NULL, 334*c5c4113dSnw141292 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 335*c5c4113dSnw141292 'double', 1.234 336*c5c4113dSnw141292 ); 337*c5c4113dSnw141292 } 338*c5c4113dSnw141292} {1.234} 339*c5c4113dSnw141292 340*c5c4113dSnw141292# Test the built-in sqlite_version(*) SQL function. 341*c5c4113dSnw141292# 342*c5c4113dSnw141292do_test func-11.1 { 343*c5c4113dSnw141292 execsql { 344*c5c4113dSnw141292 SELECT sqlite_version(*); 345*c5c4113dSnw141292 } 346*c5c4113dSnw141292} [sqlite -version] 347*c5c4113dSnw141292 348*c5c4113dSnw141292finish_test 349