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*dddca286Sdrh# $Id: func.test,v 1.43 2006/01/03 00:33:50 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} 1828aff1015Sdrh} {0 {-2.00 1.23 2.00}} 183bf4133cbSdrhdo_test func-4.7 { 184bf4133cbSdrh catchsql {SELECT round(b,0) FROM t1 ORDER BY a} 185bf4133cbSdrh} {0 {2 1 -2}} 186bf4133cbSdrhdo_test func-4.8 { 187bf4133cbSdrh catchsql {SELECT round(c) FROM t1 ORDER BY a} 188bf4133cbSdrh} {0 {3 -12346 -5}} 189bf4133cbSdrhdo_test func-4.9 { 190bf4133cbSdrh catchsql {SELECT round(c,a) FROM t1 ORDER BY a} 191bf4133cbSdrh} {0 {3.0 -12345.68 -5.000}} 192bf4133cbSdrhdo_test func-4.10 { 19301a34661Sdrh catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a} 19401a34661Sdrh} {0 {x3.0y x-12345.68y x-5.000y}} 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} 200bb113518Sdrh} {1.00 nil 345.00 nil 67890.00} 201832508b7Sdrhdo_test func-4.13 { 202832508b7Sdrh execsql {SELECT round(t1,2) FROM tbl1} 203832508b7Sdrh} {0.00 0.00 0.00 0.00 0.00} 204832508b7Sdrh 205832508b7Sdrh# Test the upper() and lower() functions 206832508b7Sdrh# 207832508b7Sdrhdo_test func-5.1 { 208832508b7Sdrh execsql {SELECT upper(t1) FROM tbl1} 209832508b7Sdrh} {THIS PROGRAM IS FREE SOFTWARE} 210832508b7Sdrhdo_test func-5.2 { 211832508b7Sdrh execsql {SELECT lower(upper(t1)) FROM tbl1} 212832508b7Sdrh} {this program is free software} 213832508b7Sdrhdo_test func-5.3 { 214832508b7Sdrh execsql {SELECT upper(a), lower(a) FROM t2} 215832508b7Sdrh} {1 1 {} {} 345 345 {} {} 67890 67890} 216832508b7Sdrhdo_test func-5.4 { 217832508b7Sdrh catchsql {SELECT upper(a,5) FROM t2} 218832508b7Sdrh} {1 {wrong number of arguments to function upper()}} 219832508b7Sdrhdo_test func-5.5 { 220832508b7Sdrh catchsql {SELECT upper(*) FROM t2} 221832508b7Sdrh} {1 {wrong number of arguments to function upper()}} 222832508b7Sdrh 223a9f9d1c0Sdrh# Test the coalesce() and nullif() functions 224832508b7Sdrh# 225832508b7Sdrhdo_test func-6.1 { 226832508b7Sdrh execsql {SELECT coalesce(a,'xyz') FROM t2} 227832508b7Sdrh} {1 xyz 345 xyz 67890} 228832508b7Sdrhdo_test func-6.2 { 229832508b7Sdrh execsql {SELECT coalesce(upper(a),'nil') FROM t2} 230832508b7Sdrh} {1 nil 345 nil 67890} 231a9f9d1c0Sdrhdo_test func-6.3 { 232a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,1),'nil')} 233a9f9d1c0Sdrh} {nil} 234a9f9d1c0Sdrhdo_test func-6.4 { 235a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,2),'nil')} 236a9f9d1c0Sdrh} {1} 237a9f9d1c0Sdrhdo_test func-6.5 { 238a9f9d1c0Sdrh execsql {SELECT coalesce(nullif(1,NULL),'nil')} 239a9f9d1c0Sdrh} {1} 240a9f9d1c0Sdrh 241832508b7Sdrh 2426ed41ad7Sdrh# Test the last_insert_rowid() function 2436ed41ad7Sdrh# 2446ed41ad7Sdrhdo_test func-7.1 { 2456ed41ad7Sdrh execsql {SELECT last_insert_rowid()} 2466ed41ad7Sdrh} [db last_insert_rowid] 2476ed41ad7Sdrh 248739105c7Sdrh# Tests for aggregate functions and how they handle NULLs. 249739105c7Sdrh# 250739105c7Sdrhdo_test func-8.1 { 2514489f9bdSdanielk1977 ifcapable explain { 252c5cdca61Sdrh execsql {EXPLAIN SELECT sum(a) FROM t2;} 2534489f9bdSdanielk1977 } 254739105c7Sdrh execsql { 255739105c7Sdrh SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2; 256739105c7Sdrh } 2573d1d95e6Sdrh} {68236 3 22745.33 1 67890 5} 258a9f9d1c0Sdrhdo_test func-8.2 { 259a9f9d1c0Sdrh execsql { 260a9f9d1c0Sdrh SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; 261a9f9d1c0Sdrh } 262a9f9d1c0Sdrh} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 26353c0f748Sdanielk1977 26453c0f748Sdanielk1977ifcapable tempdb { 265a9f9d1c0Sdrh do_test func-8.3 { 266a9f9d1c0Sdrh execsql { 267a9f9d1c0Sdrh CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 268a9f9d1c0Sdrh SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 269a9f9d1c0Sdrh } 2709eb516c0Sdrh } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 27153c0f748Sdanielk1977} else { 27253c0f748Sdanielk1977 do_test func-8.3 { 27353c0f748Sdanielk1977 execsql { 27453c0f748Sdanielk1977 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; 27553c0f748Sdanielk1977 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 27653c0f748Sdanielk1977 } 27753c0f748Sdanielk1977 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 27853c0f748Sdanielk1977} 2793aeab9e4Sdanielk1977do_test func-8.4 { 2803aeab9e4Sdanielk1977 execsql { 2813aeab9e4Sdanielk1977 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; 2823aeab9e4Sdanielk1977 } 2833aeab9e4Sdanielk1977} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} 284739105c7Sdrh 285a9f9d1c0Sdrh# How do you test the random() function in a meaningful, deterministic way? 286a9f9d1c0Sdrh# 287a9f9d1c0Sdrhdo_test func-9.1 { 288a9f9d1c0Sdrh execsql { 289a9f9d1c0Sdrh SELECT random() is not null; 290a9f9d1c0Sdrh } 291a9f9d1c0Sdrh} {1} 292bf4133cbSdrh 2936cbe1f1bSdrh# Use the "sqlite_register_test_function" TCL command which is part of 2946cbe1f1bSdrh# the text fixture in order to verify correct operation of some of 2956cbe1f1bSdrh# the user-defined SQL function APIs that are not used by the built-in 2966cbe1f1bSdrh# functions. 2976cbe1f1bSdrh# 298*dddca286Sdrhset ::DB [sqlite3_connection_pointer db] 2996cbe1f1bSdrhsqlite_register_test_function $::DB testfunc 3006cbe1f1bSdrhdo_test func-10.1 { 3016cbe1f1bSdrh catchsql { 3026cbe1f1bSdrh SELECT testfunc(NULL,NULL); 3036cbe1f1bSdrh } 3046d88bad4Sdanielk1977} {1 {first argument should be one of: int int64 string double null value}} 3056cbe1f1bSdrhdo_test func-10.2 { 3066cbe1f1bSdrh execsql { 3076cbe1f1bSdrh SELECT testfunc( 3086cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3096cbe1f1bSdrh 'int', 1234 3106cbe1f1bSdrh ); 3116cbe1f1bSdrh } 3126cbe1f1bSdrh} {1234} 3136cbe1f1bSdrhdo_test func-10.3 { 3146cbe1f1bSdrh execsql { 3156cbe1f1bSdrh SELECT testfunc( 3166cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3176cbe1f1bSdrh 'string', NULL 3186cbe1f1bSdrh ); 3196cbe1f1bSdrh } 3206cbe1f1bSdrh} {{}} 3216cbe1f1bSdrhdo_test func-10.4 { 3226cbe1f1bSdrh execsql { 3236cbe1f1bSdrh SELECT testfunc( 3246cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3256cbe1f1bSdrh 'double', 1.234 3266cbe1f1bSdrh ); 3276cbe1f1bSdrh } 3286cbe1f1bSdrh} {1.234} 3296cbe1f1bSdrhdo_test func-10.5 { 3306cbe1f1bSdrh execsql { 3316cbe1f1bSdrh SELECT testfunc( 3326cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3336cbe1f1bSdrh 'int', 1234, 3346cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3356cbe1f1bSdrh 'string', NULL, 3366cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3376cbe1f1bSdrh 'double', 1.234, 3386cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3396cbe1f1bSdrh 'int', 1234, 3406cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3416cbe1f1bSdrh 'string', NULL, 3426cbe1f1bSdrh 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 3436cbe1f1bSdrh 'double', 1.234 3446cbe1f1bSdrh ); 3456cbe1f1bSdrh } 3466cbe1f1bSdrh} {1.234} 3476cbe1f1bSdrh 348647cb0e1Sdrh# Test the built-in sqlite_version(*) SQL function. 349647cb0e1Sdrh# 350647cb0e1Sdrhdo_test func-11.1 { 351647cb0e1Sdrh execsql { 352647cb0e1Sdrh SELECT sqlite_version(*); 353647cb0e1Sdrh } 354ef4ac8f9Sdrh} [sqlite3 -version] 355647cb0e1Sdrh 356ef4ac8f9Sdrh# Test that destructors passed to sqlite3 by calls to sqlite3_result_text() 3573f6b0874Sdanielk1977# etc. are called. These tests use two special user-defined functions 3583f6b0874Sdanielk1977# (implemented in func.c) only available in test builds. 3593f6b0874Sdanielk1977# 3603f6b0874Sdanielk1977# Function test_destructor() takes one argument and returns a copy of the 3613f6b0874Sdanielk1977# text form of that argument. A destructor is associated with the return 3623f6b0874Sdanielk1977# value. Function test_destructor_count() returns the number of outstanding 3633f6b0874Sdanielk1977# destructor calls for values returned by test_destructor(). 3643f6b0874Sdanielk1977# 365d8123366Sdanielk1977do_test func-12.1 { 366d8123366Sdanielk1977 execsql { 367d8123366Sdanielk1977 SELECT test_destructor('hello world'), test_destructor_count(); 368d8123366Sdanielk1977 } 369d8123366Sdanielk1977} {{hello world} 1} 370d8123366Sdanielk1977do_test func-12.2 { 371d8123366Sdanielk1977 execsql { 372d8123366Sdanielk1977 SELECT test_destructor_count(); 373d8123366Sdanielk1977 } 374d8123366Sdanielk1977} {0} 375d8123366Sdanielk1977do_test func-12.3 { 376d8123366Sdanielk1977 execsql { 377d8123366Sdanielk1977 SELECT test_destructor('hello')||' world', test_destructor_count(); 378d8123366Sdanielk1977 } 379d8123366Sdanielk1977} {{hello world} 0} 380d8123366Sdanielk1977do_test func-12.4 { 381d8123366Sdanielk1977 execsql { 382d8123366Sdanielk1977 SELECT test_destructor_count(); 383d8123366Sdanielk1977 } 384d8123366Sdanielk1977} {0} 385d8123366Sdanielk1977do_test func-12.5 { 386d8123366Sdanielk1977 execsql { 387d8123366Sdanielk1977 CREATE TABLE t4(x); 388d8123366Sdanielk1977 INSERT INTO t4 VALUES(test_destructor('hello')); 389d8123366Sdanielk1977 INSERT INTO t4 VALUES(test_destructor('world')); 390d8123366Sdanielk1977 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4; 391d8123366Sdanielk1977 } 392d8123366Sdanielk1977} {hello world} 393d8123366Sdanielk1977do_test func-12.6 { 394d8123366Sdanielk1977 execsql { 395d8123366Sdanielk1977 SELECT test_destructor_count(); 396d8123366Sdanielk1977 } 397d8123366Sdanielk1977} {0} 3983f6b0874Sdanielk1977do_test func-12.7 { 3993f6b0874Sdanielk1977 execsql { 4003f6b0874Sdanielk1977 DROP TABLE t4; 4013f6b0874Sdanielk1977 } 4023f6b0874Sdanielk1977} {} 4033f6b0874Sdanielk1977 4043f6b0874Sdanielk1977# Test that the auxdata API for scalar functions works. This test uses 4053f6b0874Sdanielk1977# a special user-defined function only available in test builds, 4063f6b0874Sdanielk1977# test_auxdata(). Function test_auxdata() takes any number of arguments. 4073f6b0874Sdanielk1977do_test func-13.1 { 4083f6b0874Sdanielk1977 execsql { 4093f6b0874Sdanielk1977 SELECT test_auxdata('hello world'); 4103f6b0874Sdanielk1977 } 4113f6b0874Sdanielk1977} {0} 412ece80f1eSdanielk1977 4133f6b0874Sdanielk1977do_test func-13.2 { 4143f6b0874Sdanielk1977 execsql { 4153f6b0874Sdanielk1977 CREATE TABLE t4(a, b); 4163f6b0874Sdanielk1977 INSERT INTO t4 VALUES('abc', 'def'); 4173f6b0874Sdanielk1977 INSERT INTO t4 VALUES('ghi', 'jkl'); 4183f6b0874Sdanielk1977 } 4193f6b0874Sdanielk1977} {} 4203f6b0874Sdanielk1977do_test func-13.3 { 4213f6b0874Sdanielk1977 execsql { 4223f6b0874Sdanielk1977 SELECT test_auxdata('hello world') FROM t4; 4233f6b0874Sdanielk1977 } 4243f6b0874Sdanielk1977} {0 1} 4253f6b0874Sdanielk1977do_test func-13.4 { 4263f6b0874Sdanielk1977 execsql { 4273f6b0874Sdanielk1977 SELECT test_auxdata('hello world', 123) FROM t4; 4283f6b0874Sdanielk1977 } 4293f6b0874Sdanielk1977} {{0 0} {1 1}} 4303f6b0874Sdanielk1977do_test func-13.5 { 4313f6b0874Sdanielk1977 execsql { 4323f6b0874Sdanielk1977 SELECT test_auxdata('hello world', a) FROM t4; 4333f6b0874Sdanielk1977 } 4343f6b0874Sdanielk1977} {{0 0} {1 0}} 4353f6b0874Sdanielk1977do_test func-13.6 { 4363f6b0874Sdanielk1977 execsql { 4373f6b0874Sdanielk1977 SELECT test_auxdata('hello'||'world', a) FROM t4; 4383f6b0874Sdanielk1977 } 4393f6b0874Sdanielk1977} {{0 0} {1 0}} 4403f6b0874Sdanielk1977 4413f6b0874Sdanielk1977# Test that auxilary data is preserved between calls for SQL variables. 4423f6b0874Sdanielk1977do_test func-13.7 { 443*dddca286Sdrh set DB [sqlite3_connection_pointer db] 4443f6b0874Sdanielk1977 set sql "SELECT test_auxdata( ? , a ) FROM t4;" 4453f6b0874Sdanielk1977 set STMT [sqlite3_prepare $DB $sql -1 TAIL] 4463f6b0874Sdanielk1977 sqlite3_bind_text $STMT 1 hello -1 4473f6b0874Sdanielk1977 set res [list] 4483f6b0874Sdanielk1977 while { "SQLITE_ROW"==[sqlite3_step $STMT] } { 4493f6b0874Sdanielk1977 lappend res [sqlite3_column_text $STMT 0] 4503f6b0874Sdanielk1977 } 4513f6b0874Sdanielk1977 lappend res [sqlite3_finalize $STMT] 4523f6b0874Sdanielk1977} {{0 0} {1 0} SQLITE_OK} 453d8123366Sdanielk1977 454312d6b36Sdanielk1977# Make sure that a function with a very long name is rejected 455312d6b36Sdanielk1977do_test func-14.1 { 456312d6b36Sdanielk1977 catch { 457312d6b36Sdanielk1977 db function [string repeat X 254] {return "hello"} 458312d6b36Sdanielk1977 } 459312d6b36Sdanielk1977} {0} 460312d6b36Sdanielk1977do_test func-14.2 { 461312d6b36Sdanielk1977 catch { 462312d6b36Sdanielk1977 db function [string repeat X 256] {return "hello"} 463312d6b36Sdanielk1977 } 464312d6b36Sdanielk1977} {1} 465312d6b36Sdanielk1977 46601427a62Sdanielk1977do_test func-15.1 { 46701427a62Sdanielk1977 catchsql { 46801427a62Sdanielk1977 select test_error(NULL); 46901427a62Sdanielk1977 } 47001427a62Sdanielk1977} {1 {user function error}} 47101427a62Sdanielk1977 472576ec6b3Sdanielk1977# Test the quote function for BLOB and NULL values. 473576ec6b3Sdanielk1977do_test func-16.1 { 474576ec6b3Sdanielk1977 execsql { 475576ec6b3Sdanielk1977 CREATE TABLE tbl2(a, b); 476576ec6b3Sdanielk1977 } 477576ec6b3Sdanielk1977 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL] 478576ec6b3Sdanielk1977 sqlite3_bind_blob $::STMT 1 abc 3 479576ec6b3Sdanielk1977 sqlite3_step $::STMT 480576ec6b3Sdanielk1977 sqlite3_finalize $::STMT 481576ec6b3Sdanielk1977 execsql { 482576ec6b3Sdanielk1977 SELECT quote(a), quote(b) FROM tbl2; 483576ec6b3Sdanielk1977 } 484576ec6b3Sdanielk1977} {X'616263' NULL} 485576ec6b3Sdanielk1977 4862501eb1dSdrh# Correctly handle function error messages that include %. Ticket #1354 4872501eb1dSdrh# 4882501eb1dSdrhdo_test func-17.1 { 4892501eb1dSdrh proc testfunc1 args {error "Error %d with %s percents %p"} 4902501eb1dSdrh db function testfunc1 ::testfunc1 4912501eb1dSdrh catchsql { 4922501eb1dSdrh SELECT testfunc1(1,2,3); 4932501eb1dSdrh } 4942501eb1dSdrh} {1 {Error %d with %s percents %p}} 4952501eb1dSdrh 4963d1d95e6Sdrh# The SUM function should return integer results when all inputs are integer. 4973d1d95e6Sdrh# 4983d1d95e6Sdrhdo_test func-18.1 { 4993d1d95e6Sdrh execsql { 5003d1d95e6Sdrh CREATE TABLE t5(x); 5013d1d95e6Sdrh INSERT INTO t5 VALUES(1); 5023d1d95e6Sdrh INSERT INTO t5 VALUES(-99); 5033d1d95e6Sdrh INSERT INTO t5 VALUES(10000); 5043d1d95e6Sdrh SELECT sum(x) FROM t5; 5053d1d95e6Sdrh } 5063d1d95e6Sdrh} {9902} 5073d1d95e6Sdrhdo_test func-18.2 { 5083d1d95e6Sdrh execsql { 5093d1d95e6Sdrh INSERT INTO t5 VALUES(0.0); 5103d1d95e6Sdrh SELECT sum(x) FROM t5; 5113d1d95e6Sdrh } 5128a51256cSdrh} {9902.0} 513576ec6b3Sdanielk1977 514c2bd913aSdrh# The sum of nothing is NULL. But the sum of all NULLs is NULL. 5153f219f46Sdrh# 5163f219f46Sdrhdo_test func-18.3 { 5173f219f46Sdrh execsql { 5183f219f46Sdrh DELETE FROM t5; 5193f219f46Sdrh SELECT sum(x) FROM t5; 5203f219f46Sdrh } 521c2bd913aSdrh} {{}} 5223f219f46Sdrhdo_test func-18.4 { 5233f219f46Sdrh execsql { 5243f219f46Sdrh INSERT INTO t5 VALUES(NULL); 5253f219f46Sdrh SELECT sum(x) FROM t5 5263f219f46Sdrh } 5273f219f46Sdrh} {{}} 5283f219f46Sdrhdo_test func-18.5 { 5293f219f46Sdrh execsql { 5303f219f46Sdrh INSERT INTO t5 VALUES(NULL); 5313f219f46Sdrh SELECT sum(x) FROM t5 5323f219f46Sdrh } 5333f219f46Sdrh} {{}} 5343f219f46Sdrhdo_test func-18.6 { 5353f219f46Sdrh execsql { 5363f219f46Sdrh INSERT INTO t5 VALUES(123); 5373f219f46Sdrh SELECT sum(x) FROM t5 5383f219f46Sdrh } 5393f219f46Sdrh} {123} 5405708d2deSdrh 5415708d2deSdrhfinish_test 542