blob: 6664d27b16a4f5cbc20453b94f58996309884024 [file] [log] [blame]
drhb19a2bc2001-09-16 00:13:26 +00001# 2001 September 15
drhff6e9112000-08-28 16:21:58 +00002#
drhb19a2bc2001-09-16 00:13:26 +00003# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
drhff6e9112000-08-28 16:21:58 +00005#
drhb19a2bc2001-09-16 00:13:26 +00006# May you do good and not evil.
7# May you find forgiveness for yourself and forgive others.
8# May you share freely, never taking more than you give.
drhff6e9112000-08-28 16:21:58 +00009#
10#***********************************************************************
11# This file implements regression tests for SQLite library. The
12# focus of this file is testing built-in functions.
13#
drh8dc09a02009-04-15 15:16:53 +000014# $Id: func.test,v 1.92 2009/04/15 15:16:53 drh Exp $
drhff6e9112000-08-28 16:21:58 +000015
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
19# Create a table to work with.
20#
drhff6e9112000-08-28 16:21:58 +000021do_test func-0.0 {
drh297ecf12001-04-05 15:57:13 +000022 execsql {CREATE TABLE tbl1(t1 text)}
23 foreach word {this program is free software} {
24 execsql "INSERT INTO tbl1 VALUES('$word')"
25 }
drhff6e9112000-08-28 16:21:58 +000026 execsql {SELECT t1 FROM tbl1 ORDER BY t1}
27} {free is program software this}
drh832508b2002-03-02 17:04:07 +000028do_test func-0.1 {
29 execsql {
30 CREATE TABLE t2(a);
31 INSERT INTO t2 VALUES(1);
32 INSERT INTO t2 VALUES(NULL);
33 INSERT INTO t2 VALUES(345);
34 INSERT INTO t2 VALUES(NULL);
35 INSERT INTO t2 VALUES(67890);
36 SELECT * FROM t2;
37 }
38} {1 {} 345 {} 67890}
drhff6e9112000-08-28 16:21:58 +000039
40# Check out the length() function
41#
42do_test func-1.0 {
43 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
44} {4 2 7 8 4}
45do_test func-1.1 {
46 set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
47 lappend r $msg
drh89425d52002-02-28 03:04:48 +000048} {1 {wrong number of arguments to function length()}}
drhff6e9112000-08-28 16:21:58 +000049do_test func-1.2 {
50 set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
51 lappend r $msg
drh89425d52002-02-28 03:04:48 +000052} {1 {wrong number of arguments to function length()}}
drhff6e9112000-08-28 16:21:58 +000053do_test func-1.3 {
54 execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1)
55 ORDER BY length(t1)}
56} {2 1 4 2 7 1 8 1}
drh832508b2002-03-02 17:04:07 +000057do_test func-1.4 {
drhbb113512002-05-27 01:04:51 +000058 execsql {SELECT coalesce(length(a),-1) FROM t2}
59} {1 -1 3 -1 5}
drhff6e9112000-08-28 16:21:58 +000060
61# Check out the substr() function
62#
63do_test func-2.0 {
64 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
65} {fr is pr so th}
66do_test func-2.1 {
67 execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1}
68} {r s r o h}
69do_test func-2.2 {
70 execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1}
71} {ee {} ogr ftw is}
72do_test func-2.3 {
73 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
74} {e s m e s}
75do_test func-2.4 {
76 execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1}
77} {e s m e s}
78do_test func-2.5 {
79 execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1}
80} {e i a r i}
81do_test func-2.6 {
82 execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1}
83} {ee is am re is}
84do_test func-2.7 {
85 execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1}
86} {fr {} gr wa th}
87do_test func-2.8 {
88 execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)}
89} {this software free program is}
drh832508b2002-03-02 17:04:07 +000090do_test func-2.9 {
91 execsql {SELECT substr(a,1,1) FROM t2}
92} {1 {} 3 {} 6}
93do_test func-2.10 {
94 execsql {SELECT substr(a,2,2) FROM t2}
95} {{} {} 45 {} 78}
drhff6e9112000-08-28 16:21:58 +000096
drhdf014892004-06-02 00:41:09 +000097# Only do the following tests if TCL has UTF-8 capabilities
drh297ecf12001-04-05 15:57:13 +000098#
drhdf014892004-06-02 00:41:09 +000099if {"\u1234"!="u1234"} {
drh297ecf12001-04-05 15:57:13 +0000100
101# Put some UTF-8 characters in the database
102#
103do_test func-3.0 {
104 execsql {DELETE FROM tbl1}
105 foreach word "contains UTF-8 characters hi\u1234ho" {
106 execsql "INSERT INTO tbl1 VALUES('$word')"
107 }
108 execsql {SELECT t1 FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000109} "UTF-8 characters contains hi\u1234ho"
drh297ecf12001-04-05 15:57:13 +0000110do_test func-3.1 {
111 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000112} {5 10 8 5}
drh297ecf12001-04-05 15:57:13 +0000113do_test func-3.2 {
114 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000115} {UT ch co hi}
drh297ecf12001-04-05 15:57:13 +0000116do_test func-3.3 {
117 execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000118} "UTF cha con hi\u1234"
drh297ecf12001-04-05 15:57:13 +0000119do_test func-3.4 {
120 execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000121} "TF ha on i\u1234"
drh297ecf12001-04-05 15:57:13 +0000122do_test func-3.5 {
123 execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000124} "TF- har ont i\u1234h"
drh297ecf12001-04-05 15:57:13 +0000125do_test func-3.6 {
126 execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000127} "F- ar nt \u1234h"
drh297ecf12001-04-05 15:57:13 +0000128do_test func-3.7 {
129 execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000130} "-8 ra ta ho"
drh297ecf12001-04-05 15:57:13 +0000131do_test func-3.8 {
132 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000133} "8 s s o"
drh297ecf12001-04-05 15:57:13 +0000134do_test func-3.9 {
135 execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000136} "F- er in \u1234h"
drh297ecf12001-04-05 15:57:13 +0000137do_test func-3.10 {
138 execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000139} "TF- ter ain i\u1234h"
drh832508b2002-03-02 17:04:07 +0000140do_test func-3.99 {
141 execsql {DELETE FROM tbl1}
142 foreach word {this program is free software} {
143 execsql "INSERT INTO tbl1 VALUES('$word')"
144 }
145 execsql {SELECT t1 FROM tbl1}
146} {this program is free software}
drh297ecf12001-04-05 15:57:13 +0000147
drhdf014892004-06-02 00:41:09 +0000148} ;# End \u1234!=u1234
drh297ecf12001-04-05 15:57:13 +0000149
drhbf4133c2001-10-13 02:59:08 +0000150# Test the abs() and round() functions.
151#
shanefbd60f82009-02-04 03:59:25 +0000152ifcapable !floatingpoint {
153 do_test func-4.1 {
154 execsql {
155 CREATE TABLE t1(a,b,c);
156 INSERT INTO t1 VALUES(1,2,3);
157 INSERT INTO t1 VALUES(2,12345678901234,-1234567890);
158 INSERT INTO t1 VALUES(3,-2,-5);
159 }
160 catchsql {SELECT abs(a,b) FROM t1}
161 } {1 {wrong number of arguments to function abs()}}
162}
163ifcapable floatingpoint {
164 do_test func-4.1 {
165 execsql {
166 CREATE TABLE t1(a,b,c);
167 INSERT INTO t1 VALUES(1,2,3);
168 INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
169 INSERT INTO t1 VALUES(3,-2,-5);
170 }
171 catchsql {SELECT abs(a,b) FROM t1}
172 } {1 {wrong number of arguments to function abs()}}
173}
drhbf4133c2001-10-13 02:59:08 +0000174do_test func-4.2 {
175 catchsql {SELECT abs() FROM t1}
drh89425d52002-02-28 03:04:48 +0000176} {1 {wrong number of arguments to function abs()}}
shanefbd60f82009-02-04 03:59:25 +0000177ifcapable floatingpoint {
178 do_test func-4.3 {
179 catchsql {SELECT abs(b) FROM t1 ORDER BY a}
180 } {0 {2 1.2345678901234 2}}
181 do_test func-4.4 {
182 catchsql {SELECT abs(c) FROM t1 ORDER BY a}
183 } {0 {3 12345.6789 5}}
184}
185ifcapable !floatingpoint {
186 if {[working_64bit_int]} {
187 do_test func-4.3 {
188 catchsql {SELECT abs(b) FROM t1 ORDER BY a}
189 } {0 {2 12345678901234 2}}
190 }
191 do_test func-4.4 {
192 catchsql {SELECT abs(c) FROM t1 ORDER BY a}
193 } {0 {3 1234567890 5}}
194}
drh832508b2002-03-02 17:04:07 +0000195do_test func-4.4.1 {
196 execsql {SELECT abs(a) FROM t2}
197} {1 {} 345 {} 67890}
198do_test func-4.4.2 {
199 execsql {SELECT abs(t1) FROM tbl1}
drh92febd92004-08-20 18:34:20 +0000200} {0.0 0.0 0.0 0.0 0.0}
drhbf4133c2001-10-13 02:59:08 +0000201
shanefbd60f82009-02-04 03:59:25 +0000202ifcapable floatingpoint {
203 do_test func-4.5 {
204 catchsql {SELECT round(a,b,c) FROM t1}
205 } {1 {wrong number of arguments to function round()}}
206 do_test func-4.6 {
207 catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
208 } {0 {-2.0 1.23 2.0}}
209 do_test func-4.7 {
210 catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
211 } {0 {2.0 1.0 -2.0}}
212 do_test func-4.8 {
213 catchsql {SELECT round(c) FROM t1 ORDER BY a}
214 } {0 {3.0 -12346.0 -5.0}}
215 do_test func-4.9 {
216 catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
217 } {0 {3.0 -12345.68 -5.0}}
218 do_test func-4.10 {
219 catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a}
220 } {0 {x3.0y x-12345.68y x-5.0y}}
221 do_test func-4.11 {
222 catchsql {SELECT round() FROM t1 ORDER BY a}
223 } {1 {wrong number of arguments to function round()}}
224 do_test func-4.12 {
225 execsql {SELECT coalesce(round(a,2),'nil') FROM t2}
226 } {1.0 nil 345.0 nil 67890.0}
227 do_test func-4.13 {
228 execsql {SELECT round(t1,2) FROM tbl1}
229 } {0.0 0.0 0.0 0.0 0.0}
230 do_test func-4.14 {
231 execsql {SELECT typeof(round(5.1,1));}
232 } {real}
233 do_test func-4.15 {
234 execsql {SELECT typeof(round(5.1));}
235 } {real}
236 do_test func-4.16 {
237 catchsql {SELECT round(b,2.0) FROM t1 ORDER BY b}
238 } {0 {-2.0 1.23 2.0}}
239}
drh832508b2002-03-02 17:04:07 +0000240
241# Test the upper() and lower() functions
242#
243do_test func-5.1 {
244 execsql {SELECT upper(t1) FROM tbl1}
245} {THIS PROGRAM IS FREE SOFTWARE}
246do_test func-5.2 {
247 execsql {SELECT lower(upper(t1)) FROM tbl1}
248} {this program is free software}
249do_test func-5.3 {
250 execsql {SELECT upper(a), lower(a) FROM t2}
251} {1 1 {} {} 345 345 {} {} 67890 67890}
danielk19777de68a02007-05-07 16:58:02 +0000252ifcapable !icu {
253 do_test func-5.4 {
254 catchsql {SELECT upper(a,5) FROM t2}
255 } {1 {wrong number of arguments to function upper()}}
256}
drh832508b2002-03-02 17:04:07 +0000257do_test func-5.5 {
258 catchsql {SELECT upper(*) FROM t2}
259} {1 {wrong number of arguments to function upper()}}
260
drha9f9d1c2002-06-29 02:20:08 +0000261# Test the coalesce() and nullif() functions
drh832508b2002-03-02 17:04:07 +0000262#
263do_test func-6.1 {
264 execsql {SELECT coalesce(a,'xyz') FROM t2}
265} {1 xyz 345 xyz 67890}
266do_test func-6.2 {
267 execsql {SELECT coalesce(upper(a),'nil') FROM t2}
268} {1 nil 345 nil 67890}
drha9f9d1c2002-06-29 02:20:08 +0000269do_test func-6.3 {
270 execsql {SELECT coalesce(nullif(1,1),'nil')}
271} {nil}
272do_test func-6.4 {
273 execsql {SELECT coalesce(nullif(1,2),'nil')}
274} {1}
275do_test func-6.5 {
276 execsql {SELECT coalesce(nullif(1,NULL),'nil')}
277} {1}
278
drh832508b2002-03-02 17:04:07 +0000279
drh6ed41ad2002-04-06 14:10:47 +0000280# Test the last_insert_rowid() function
281#
282do_test func-7.1 {
283 execsql {SELECT last_insert_rowid()}
284} [db last_insert_rowid]
285
drh739105c2002-05-29 23:22:23 +0000286# Tests for aggregate functions and how they handle NULLs.
287#
shanefbd60f82009-02-04 03:59:25 +0000288ifcapable floatingpoint {
289 do_test func-8.1 {
290 ifcapable explain {
291 execsql {EXPLAIN SELECT sum(a) FROM t2;}
292 }
293 execsql {
294 SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
295 }
296 } {68236 3 22745.33 1 67890 5}
297}
298ifcapable !floatingpoint {
299 do_test func-8.1 {
300 ifcapable explain {
301 execsql {EXPLAIN SELECT sum(a) FROM t2;}
302 }
303 execsql {
304 SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2;
305 }
306 } {68236 3 22745.0 1 67890 5}
307}
drha9f9d1c2002-06-29 02:20:08 +0000308do_test func-8.2 {
309 execsql {
310 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
311 }
312} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
danielk197753c0f742005-03-29 03:10:59 +0000313
314ifcapable tempdb {
315 do_test func-8.3 {
316 execsql {
317 CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
318 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
319 }
320 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
321} else {
322 do_test func-8.3 {
323 execsql {
324 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
325 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
326 }
327 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
328}
danielk19773aeab9e2004-06-24 00:20:04 +0000329do_test func-8.4 {
330 execsql {
331 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
332 }
333} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
danielk1977de3e41e2008-08-04 03:51:24 +0000334ifcapable compound {
335 do_test func-8.5 {
336 execsql {
337 SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
338 UNION ALL SELECT -9223372036854775807)
339 }
340 } {0}
341 do_test func-8.6 {
342 execsql {
343 SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
344 UNION ALL SELECT -9223372036854775807)
345 }
346 } {integer}
347 do_test func-8.7 {
348 execsql {
349 SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
350 UNION ALL SELECT -9223372036854775807)
351 }
352 } {real}
shanefbd60f82009-02-04 03:59:25 +0000353ifcapable floatingpoint {
danielk1977de3e41e2008-08-04 03:51:24 +0000354 do_test func-8.8 {
355 execsql {
356 SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
357 UNION ALL SELECT -9223372036850000000)
358 }
359 } {1}
360}
shanefbd60f82009-02-04 03:59:25 +0000361ifcapable !floatingpoint {
362 do_test func-8.8 {
363 execsql {
364 SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x
365 UNION ALL SELECT -9223372036850000000)
366 }
367 } {1}
368}
369}
drh739105c2002-05-29 23:22:23 +0000370
drha9f9d1c2002-06-29 02:20:08 +0000371# How do you test the random() function in a meaningful, deterministic way?
372#
373do_test func-9.1 {
374 execsql {
375 SELECT random() is not null;
376 }
377} {1}
drh63cf66f2007-01-29 15:50:05 +0000378do_test func-9.2 {
379 execsql {
380 SELECT typeof(random());
381 }
382} {integer}
383do_test func-9.3 {
384 execsql {
drh137c7282007-01-29 17:58:28 +0000385 SELECT randomblob(32) is not null;
drh63cf66f2007-01-29 15:50:05 +0000386 }
387} {1}
388do_test func-9.4 {
389 execsql {
drh137c7282007-01-29 17:58:28 +0000390 SELECT typeof(randomblob(32));
drh63cf66f2007-01-29 15:50:05 +0000391 }
drh137c7282007-01-29 17:58:28 +0000392} {blob}
drh63cf66f2007-01-29 15:50:05 +0000393do_test func-9.5 {
394 execsql {
drh137c7282007-01-29 17:58:28 +0000395 SELECT length(randomblob(32)), length(randomblob(-5)),
396 length(randomblob(2000))
drh63cf66f2007-01-29 15:50:05 +0000397 }
drh137c7282007-01-29 17:58:28 +0000398} {32 1 2000}
drh63cf66f2007-01-29 15:50:05 +0000399
drh137c7282007-01-29 17:58:28 +0000400# The "hex()" function was added in order to be able to render blobs
401# generated by randomblob(). So this seems like a good place to test
402# hex().
403#
danielk19774152e672007-09-12 17:01:45 +0000404ifcapable bloblit {
405 do_test func-9.10 {
406 execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
407 } {00112233445566778899AABBCCDDEEFF}
408}
drh056c8f72007-05-15 18:35:21 +0000409set encoding [db one {PRAGMA encoding}]
410if {$encoding=="UTF-16le"} {
411 do_test func-9.11-utf16le {
412 execsql {SELECT hex(replace('abcdefg','ef','12'))}
413 } {6100620063006400310032006700}
414 do_test func-9.12-utf16le {
415 execsql {SELECT hex(replace('abcdefg','','12'))}
drha605fe82009-02-01 18:08:40 +0000416 } {6100620063006400650066006700}
drh056c8f72007-05-15 18:35:21 +0000417 do_test func-9.13-utf16le {
418 execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
419 } {610061006100610061006100620063006400650066006700}
420} elseif {$encoding=="UTF-8"} {
421 do_test func-9.11-utf8 {
422 execsql {SELECT hex(replace('abcdefg','ef','12'))}
423 } {61626364313267}
424 do_test func-9.12-utf8 {
425 execsql {SELECT hex(replace('abcdefg','','12'))}
drha605fe82009-02-01 18:08:40 +0000426 } {61626364656667}
drh056c8f72007-05-15 18:35:21 +0000427 do_test func-9.13-utf8 {
428 execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
429 } {616161616161626364656667}
430}
431
drh6cbe1f12002-07-01 00:31:36 +0000432# Use the "sqlite_register_test_function" TCL command which is part of
433# the text fixture in order to verify correct operation of some of
434# the user-defined SQL function APIs that are not used by the built-in
435# functions.
436#
drhdddca282006-01-03 00:33:50 +0000437set ::DB [sqlite3_connection_pointer db]
drh6cbe1f12002-07-01 00:31:36 +0000438sqlite_register_test_function $::DB testfunc
439do_test func-10.1 {
440 catchsql {
441 SELECT testfunc(NULL,NULL);
442 }
danielk19776d88bad2004-05-27 14:23:36 +0000443} {1 {first argument should be one of: int int64 string double null value}}
drh6cbe1f12002-07-01 00:31:36 +0000444do_test func-10.2 {
445 execsql {
446 SELECT testfunc(
447 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
448 'int', 1234
449 );
450 }
451} {1234}
452do_test func-10.3 {
453 execsql {
454 SELECT testfunc(
455 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
456 'string', NULL
457 );
458 }
459} {{}}
shanefbd60f82009-02-04 03:59:25 +0000460
461ifcapable floatingpoint {
462 do_test func-10.4 {
463 execsql {
464 SELECT testfunc(
465 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
466 'double', 1.234
467 );
468 }
469 } {1.234}
470 do_test func-10.5 {
471 execsql {
472 SELECT testfunc(
473 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
474 'int', 1234,
475 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
476 'string', NULL,
477 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
478 'double', 1.234,
479 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
480 'int', 1234,
481 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
482 'string', NULL,
483 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
484 'double', 1.234
485 );
486 }
487 } {1.234}
488}
drh6cbe1f12002-07-01 00:31:36 +0000489
drh647cb0e2002-11-04 19:32:25 +0000490# Test the built-in sqlite_version(*) SQL function.
491#
492do_test func-11.1 {
493 execsql {
494 SELECT sqlite_version(*);
495 }
drhef4ac8f2004-06-19 00:16:31 +0000496} [sqlite3 -version]
drh647cb0e2002-11-04 19:32:25 +0000497
drhef4ac8f2004-06-19 00:16:31 +0000498# Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
danielk19773f6b0872004-06-17 05:36:44 +0000499# etc. are called. These tests use two special user-defined functions
500# (implemented in func.c) only available in test builds.
501#
502# Function test_destructor() takes one argument and returns a copy of the
503# text form of that argument. A destructor is associated with the return
504# value. Function test_destructor_count() returns the number of outstanding
505# destructor calls for values returned by test_destructor().
506#
drhda84ca82008-03-19 16:35:24 +0000507if {[db eval {PRAGMA encoding}]=="UTF-8"} {
508 do_test func-12.1-utf8 {
509 execsql {
510 SELECT test_destructor('hello world'), test_destructor_count();
511 }
512 } {{hello world} 1}
513} else {
shane2a5fc4d2008-07-31 01:47:11 +0000514 ifcapable {utf16} {
515 do_test func-12.1-utf16 {
516 execsql {
517 SELECT test_destructor16('hello world'), test_destructor_count();
518 }
519 } {{hello world} 1}
drhda84ca82008-03-19 16:35:24 +0000520 }
drhda84ca82008-03-19 16:35:24 +0000521}
danielk1977d8123362004-06-12 09:25:12 +0000522do_test func-12.2 {
523 execsql {
524 SELECT test_destructor_count();
525 }
526} {0}
527do_test func-12.3 {
528 execsql {
drh2dcef112008-01-12 19:03:48 +0000529 SELECT test_destructor('hello')||' world'
danielk1977d8123362004-06-12 09:25:12 +0000530 }
drh2dcef112008-01-12 19:03:48 +0000531} {{hello world}}
danielk1977d8123362004-06-12 09:25:12 +0000532do_test func-12.4 {
533 execsql {
534 SELECT test_destructor_count();
535 }
536} {0}
537do_test func-12.5 {
538 execsql {
539 CREATE TABLE t4(x);
540 INSERT INTO t4 VALUES(test_destructor('hello'));
541 INSERT INTO t4 VALUES(test_destructor('world'));
542 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
543 }
544} {hello world}
545do_test func-12.6 {
546 execsql {
547 SELECT test_destructor_count();
548 }
549} {0}
danielk19773f6b0872004-06-17 05:36:44 +0000550do_test func-12.7 {
551 execsql {
552 DROP TABLE t4;
553 }
554} {}
555
drha4e5d582007-10-20 15:41:57 +0000556
danielk19773f6b0872004-06-17 05:36:44 +0000557# Test that the auxdata API for scalar functions works. This test uses
558# a special user-defined function only available in test builds,
559# test_auxdata(). Function test_auxdata() takes any number of arguments.
560do_test func-13.1 {
561 execsql {
562 SELECT test_auxdata('hello world');
563 }
564} {0}
danielk1977ece80f12004-06-23 01:05:26 +0000565
danielk19773f6b0872004-06-17 05:36:44 +0000566do_test func-13.2 {
567 execsql {
568 CREATE TABLE t4(a, b);
569 INSERT INTO t4 VALUES('abc', 'def');
570 INSERT INTO t4 VALUES('ghi', 'jkl');
571 }
572} {}
573do_test func-13.3 {
574 execsql {
575 SELECT test_auxdata('hello world') FROM t4;
576 }
577} {0 1}
578do_test func-13.4 {
579 execsql {
580 SELECT test_auxdata('hello world', 123) FROM t4;
581 }
582} {{0 0} {1 1}}
583do_test func-13.5 {
584 execsql {
585 SELECT test_auxdata('hello world', a) FROM t4;
586 }
587} {{0 0} {1 0}}
588do_test func-13.6 {
589 execsql {
590 SELECT test_auxdata('hello'||'world', a) FROM t4;
591 }
592} {{0 0} {1 0}}
593
594# Test that auxilary data is preserved between calls for SQL variables.
595do_test func-13.7 {
drhdddca282006-01-03 00:33:50 +0000596 set DB [sqlite3_connection_pointer db]
danielk19773f6b0872004-06-17 05:36:44 +0000597 set sql "SELECT test_auxdata( ? , a ) FROM t4;"
598 set STMT [sqlite3_prepare $DB $sql -1 TAIL]
drh10dfbbb2008-04-16 12:58:53 +0000599 sqlite3_bind_text $STMT 1 hello\000 -1
danielk19773f6b0872004-06-17 05:36:44 +0000600 set res [list]
601 while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
602 lappend res [sqlite3_column_text $STMT 0]
603 }
604 lappend res [sqlite3_finalize $STMT]
605} {{0 0} {1 0} SQLITE_OK}
danielk1977d8123362004-06-12 09:25:12 +0000606
danielk1977312d6b32004-06-29 13:18:23 +0000607# Make sure that a function with a very long name is rejected
608do_test func-14.1 {
609 catch {
610 db function [string repeat X 254] {return "hello"}
611 }
612} {0}
613do_test func-14.2 {
614 catch {
615 db function [string repeat X 256] {return "hello"}
616 }
617} {1}
618
danielk197701427a62005-01-11 13:02:33 +0000619do_test func-15.1 {
drh00e087b2008-04-10 17:14:07 +0000620 catchsql {select test_error(NULL)}
drh90669c12006-01-20 15:45:36 +0000621} {1 {}}
drh00e087b2008-04-10 17:14:07 +0000622do_test func-15.2 {
623 catchsql {select test_error('this is the error message')}
624} {1 {this is the error message}}
625do_test func-15.3 {
626 catchsql {select test_error('this is the error message',12)}
627} {1 {this is the error message}}
628do_test func-15.4 {
629 db errorcode
630} {12}
danielk197701427a62005-01-11 13:02:33 +0000631
danielk1977576ec6b2005-01-21 11:55:25 +0000632# Test the quote function for BLOB and NULL values.
633do_test func-16.1 {
634 execsql {
635 CREATE TABLE tbl2(a, b);
636 }
637 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
638 sqlite3_bind_blob $::STMT 1 abc 3
639 sqlite3_step $::STMT
640 sqlite3_finalize $::STMT
641 execsql {
642 SELECT quote(a), quote(b) FROM tbl2;
643 }
644} {X'616263' NULL}
645
drh2501eb12005-08-12 23:20:53 +0000646# Correctly handle function error messages that include %. Ticket #1354
647#
648do_test func-17.1 {
649 proc testfunc1 args {error "Error %d with %s percents %p"}
650 db function testfunc1 ::testfunc1
651 catchsql {
652 SELECT testfunc1(1,2,3);
653 }
654} {1 {Error %d with %s percents %p}}
655
drh3d1d95e2005-09-08 10:37:01 +0000656# The SUM function should return integer results when all inputs are integer.
657#
658do_test func-18.1 {
659 execsql {
660 CREATE TABLE t5(x);
661 INSERT INTO t5 VALUES(1);
662 INSERT INTO t5 VALUES(-99);
663 INSERT INTO t5 VALUES(10000);
664 SELECT sum(x) FROM t5;
665 }
666} {9902}
shanefbd60f82009-02-04 03:59:25 +0000667ifcapable floatingpoint {
668 do_test func-18.2 {
669 execsql {
670 INSERT INTO t5 VALUES(0.0);
671 SELECT sum(x) FROM t5;
672 }
673 } {9902.0}
674}
danielk1977576ec6b2005-01-21 11:55:25 +0000675
drhc2bd9132005-09-08 20:37:43 +0000676# The sum of nothing is NULL. But the sum of all NULLs is NULL.
drh3f219f42005-09-08 19:45:57 +0000677#
drh76c730c2006-02-09 17:47:42 +0000678# The TOTAL of nothing is 0.0.
679#
drh3f219f42005-09-08 19:45:57 +0000680do_test func-18.3 {
681 execsql {
682 DELETE FROM t5;
drh76c730c2006-02-09 17:47:42 +0000683 SELECT sum(x), total(x) FROM t5;
drh3f219f42005-09-08 19:45:57 +0000684 }
drh76c730c2006-02-09 17:47:42 +0000685} {{} 0.0}
drh3f219f42005-09-08 19:45:57 +0000686do_test func-18.4 {
687 execsql {
688 INSERT INTO t5 VALUES(NULL);
drh76c730c2006-02-09 17:47:42 +0000689 SELECT sum(x), total(x) FROM t5
drh3f219f42005-09-08 19:45:57 +0000690 }
drh76c730c2006-02-09 17:47:42 +0000691} {{} 0.0}
drh3f219f42005-09-08 19:45:57 +0000692do_test func-18.5 {
693 execsql {
694 INSERT INTO t5 VALUES(NULL);
drh76c730c2006-02-09 17:47:42 +0000695 SELECT sum(x), total(x) FROM t5
drh3f219f42005-09-08 19:45:57 +0000696 }
drh76c730c2006-02-09 17:47:42 +0000697} {{} 0.0}
drh3f219f42005-09-08 19:45:57 +0000698do_test func-18.6 {
699 execsql {
700 INSERT INTO t5 VALUES(123);
drh76c730c2006-02-09 17:47:42 +0000701 SELECT sum(x), total(x) FROM t5
drh3f219f42005-09-08 19:45:57 +0000702 }
drh76c730c2006-02-09 17:47:42 +0000703} {123 123.0}
drh5708d2d2005-06-22 10:53:59 +0000704
drh8c08e862006-02-11 17:34:00 +0000705# Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
706# an error. The non-standard TOTAL() function continues to give a helpful
707# result.
drhfc6ad392006-02-09 13:38:19 +0000708#
709do_test func-18.10 {
710 execsql {
711 CREATE TABLE t6(x INTEGER);
712 INSERT INTO t6 VALUES(1);
713 INSERT INTO t6 VALUES(1<<62);
714 SELECT sum(x) - ((1<<62)+1) from t6;
715 }
716} 0
drh76c730c2006-02-09 17:47:42 +0000717do_test func-18.11 {
718 execsql {
719 SELECT typeof(sum(x)) FROM t6
720 }
721} integer
shanefbd60f82009-02-04 03:59:25 +0000722ifcapable floatingpoint {
723 do_test func-18.12 {
724 catchsql {
725 INSERT INTO t6 VALUES(1<<62);
726 SELECT sum(x) - ((1<<62)*2.0+1) from t6;
727 }
728 } {1 {integer overflow}}
729 do_test func-18.13 {
730 execsql {
731 SELECT total(x) - ((1<<62)*2.0+1) FROM t6
732 }
733 } 0.0
734}
735ifcapable !floatingpoint {
736 do_test func-18.12 {
737 catchsql {
738 INSERT INTO t6 VALUES(1<<62);
739 SELECT sum(x) - ((1<<62)*2+1) from t6;
740 }
741 } {1 {integer overflow}}
742 do_test func-18.13 {
743 execsql {
744 SELECT total(x) - ((1<<62)*2+1) FROM t6
745 }
746 } 0.0
747}
748if {[working_64bit_int]} {
749 do_test func-18.14 {
750 execsql {
751 SELECT sum(-9223372036854775805);
752 }
753 } -9223372036854775805
754}
danielk19774b2688a2006-06-20 11:01:07 +0000755ifcapable compound&&subquery {
756
drh8c08e862006-02-11 17:34:00 +0000757do_test func-18.15 {
758 catchsql {
759 SELECT sum(x) FROM
760 (SELECT 9223372036854775807 AS x UNION ALL
761 SELECT 10 AS x);
762 }
763} {1 {integer overflow}}
shanefbd60f82009-02-04 03:59:25 +0000764if {[working_64bit_int]} {
765 do_test func-18.16 {
766 catchsql {
767 SELECT sum(x) FROM
768 (SELECT 9223372036854775807 AS x UNION ALL
769 SELECT -10 AS x);
770 }
771 } {0 9223372036854775797}
772 do_test func-18.17 {
773 catchsql {
774 SELECT sum(x) FROM
775 (SELECT -9223372036854775807 AS x UNION ALL
776 SELECT 10 AS x);
777 }
778 } {0 -9223372036854775797}
779}
drh8c08e862006-02-11 17:34:00 +0000780do_test func-18.18 {
781 catchsql {
782 SELECT sum(x) FROM
783 (SELECT -9223372036854775807 AS x UNION ALL
784 SELECT -10 AS x);
785 }
786} {1 {integer overflow}}
787do_test func-18.19 {
788 catchsql {
789 SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
790 }
791} {0 -1}
792do_test func-18.20 {
793 catchsql {
794 SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
795 }
796} {0 1}
797do_test func-18.21 {
798 catchsql {
799 SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
800 }
801} {0 -1}
802do_test func-18.22 {
803 catchsql {
804 SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
805 }
806} {0 1}
drh76c730c2006-02-09 17:47:42 +0000807
danielk19774b2688a2006-06-20 11:01:07 +0000808} ;# ifcapable compound&&subquery
809
drh52fc8492006-02-23 21:43:55 +0000810# Integer overflow on abs()
811#
shanefbd60f82009-02-04 03:59:25 +0000812if {[working_64bit_int]} {
813 do_test func-18.31 {
814 catchsql {
815 SELECT abs(-9223372036854775807);
816 }
817 } {0 9223372036854775807}
818}
drh52fc8492006-02-23 21:43:55 +0000819do_test func-18.32 {
820 catchsql {
821 SELECT abs(-9223372036854775807-1);
822 }
823} {1 {integer overflow}}
824
drh7f375902006-06-13 17:38:59 +0000825# The MATCH function exists but is only a stub and always throws an error.
826#
827do_test func-19.1 {
828 execsql {
829 SELECT match(a,b) FROM t1 WHERE 0;
830 }
831} {}
832do_test func-19.2 {
833 catchsql {
834 SELECT 'abc' MATCH 'xyz';
835 }
drhb7481e72006-09-16 21:45:14 +0000836} {1 {unable to use function MATCH in the requested context}}
drh7f375902006-06-13 17:38:59 +0000837do_test func-19.3 {
838 catchsql {
839 SELECT 'abc' NOT MATCH 'xyz';
840 }
drhb7481e72006-09-16 21:45:14 +0000841} {1 {unable to use function MATCH in the requested context}}
drh7f375902006-06-13 17:38:59 +0000842do_test func-19.4 {
843 catchsql {
844 SELECT match(1,2,3);
845 }
846} {1 {wrong number of arguments to function match()}}
drh76c730c2006-02-09 17:47:42 +0000847
drhbdf67e02006-08-19 11:34:01 +0000848# Soundex tests.
849#
850if {![catch {db eval {SELECT soundex('hello')}}]} {
851 set i 0
852 foreach {name sdx} {
853 euler E460
854 EULER E460
855 Euler E460
856 ellery E460
857 gauss G200
858 ghosh G200
859 hilbert H416
860 Heilbronn H416
861 knuth K530
862 kant K530
863 Lloyd L300
864 LADD L300
865 Lukasiewicz L222
866 Lissajous L222
867 A A000
868 12345 ?000
869 } {
870 incr i
871 do_test func-20.$i {
872 execsql {SELECT soundex($name)}
873 } $sdx
874 }
875}
876
drh26b6d902007-03-17 13:27:54 +0000877# Tests of the REPLACE function.
878#
879do_test func-21.1 {
880 catchsql {
881 SELECT replace(1,2);
882 }
883} {1 {wrong number of arguments to function replace()}}
884do_test func-21.2 {
885 catchsql {
886 SELECT replace(1,2,3,4);
887 }
888} {1 {wrong number of arguments to function replace()}}
889do_test func-21.3 {
890 execsql {
891 SELECT typeof(replace("This is the main test string", NULL, "ALT"));
892 }
893} {null}
894do_test func-21.4 {
895 execsql {
896 SELECT typeof(replace(NULL, "main", "ALT"));
897 }
898} {null}
899do_test func-21.5 {
900 execsql {
901 SELECT typeof(replace("This is the main test string", "main", NULL));
902 }
903} {null}
904do_test func-21.6 {
905 execsql {
906 SELECT replace("This is the main test string", "main", "ALT");
907 }
908} {{This is the ALT test string}}
909do_test func-21.7 {
910 execsql {
911 SELECT replace("This is the main test string", "main", "larger-main");
912 }
913} {{This is the larger-main test string}}
914do_test func-21.8 {
915 execsql {
916 SELECT replace("aaaaaaa", "a", "0123456789");
917 }
918} {0123456789012345678901234567890123456789012345678901234567890123456789}
919
danielk19774152e672007-09-12 17:01:45 +0000920ifcapable tclvar {
921 do_test func-21.9 {
922 # Attempt to exploit a buffer-overflow that at one time existed
923 # in the REPLACE function.
924 set ::str "[string repeat A 29998]CC[string repeat A 35537]"
925 set ::rep [string repeat B 65536]
926 execsql {
927 SELECT LENGTH(REPLACE($::str, 'C', $::rep));
928 }
929 } [expr 29998 + 2*65536 + 35537]
930}
danielk197717374e82007-05-08 14:39:04 +0000931
drh309b3382007-03-17 17:52:42 +0000932# Tests for the TRIM, LTRIM and RTRIM functions.
933#
934do_test func-22.1 {
935 catchsql {SELECT trim(1,2,3)}
936} {1 {wrong number of arguments to function trim()}}
937do_test func-22.2 {
938 catchsql {SELECT ltrim(1,2,3)}
939} {1 {wrong number of arguments to function ltrim()}}
940do_test func-22.3 {
941 catchsql {SELECT rtrim(1,2,3)}
942} {1 {wrong number of arguments to function rtrim()}}
943do_test func-22.4 {
944 execsql {SELECT trim(' hi ');}
945} {hi}
946do_test func-22.5 {
947 execsql {SELECT ltrim(' hi ');}
948} {{hi }}
949do_test func-22.6 {
950 execsql {SELECT rtrim(' hi ');}
951} {{ hi}}
952do_test func-22.7 {
953 execsql {SELECT trim(' hi ','xyz');}
954} {{ hi }}
955do_test func-22.8 {
956 execsql {SELECT ltrim(' hi ','xyz');}
957} {{ hi }}
958do_test func-22.9 {
959 execsql {SELECT rtrim(' hi ','xyz');}
960} {{ hi }}
961do_test func-22.10 {
962 execsql {SELECT trim('xyxzy hi zzzy','xyz');}
963} {{ hi }}
964do_test func-22.11 {
965 execsql {SELECT ltrim('xyxzy hi zzzy','xyz');}
966} {{ hi zzzy}}
967do_test func-22.12 {
968 execsql {SELECT rtrim('xyxzy hi zzzy','xyz');}
969} {{xyxzy hi }}
970do_test func-22.13 {
971 execsql {SELECT trim(' hi ','');}
972} {{ hi }}
drh4e05c832007-05-11 01:44:50 +0000973if {[db one {PRAGMA encoding}]=="UTF-8"} {
974 do_test func-22.14 {
975 execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
976 } {F48FBFBF6869}
977 do_test func-22.15 {
978 execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
979 x'6162e1bfbfc280f48fbfbf'))}
980 } {6869}
981 do_test func-22.16 {
982 execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
983 } {CEB2CEB3}
984}
drh309b3382007-03-17 17:52:42 +0000985do_test func-22.20 {
986 execsql {SELECT typeof(trim(NULL));}
987} {null}
988do_test func-22.21 {
989 execsql {SELECT typeof(trim(NULL,'xyz'));}
990} {null}
991do_test func-22.22 {
992 execsql {SELECT typeof(trim('hello',NULL));}
993} {null}
drh26b6d902007-03-17 13:27:54 +0000994
danielk1977fa18bec2007-09-03 11:04:22 +0000995# This is to test the deprecated sqlite3_aggregate_count() API.
996#
shaneeec556d2008-10-12 00:27:53 +0000997ifcapable deprecated {
998 do_test func-23.1 {
999 sqlite3_create_aggregate db
1000 execsql {
1001 SELECT legacy_count() FROM t6;
1002 }
1003 } {3}
1004}
danielk1977fa18bec2007-09-03 11:04:22 +00001005
drhade86482007-11-28 22:36:40 +00001006# The group_concat() function.
1007#
1008do_test func-24.1 {
1009 execsql {
1010 SELECT group_concat(t1) FROM tbl1
1011 }
1012} {this,program,is,free,software}
1013do_test func-24.2 {
1014 execsql {
1015 SELECT group_concat(t1,' ') FROM tbl1
1016 }
1017} {{this program is free software}}
1018do_test func-24.3 {
1019 execsql {
1020 SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
1021 }
1022} {{this 2 program 3 is 4 free 5 software}}
1023do_test func-24.4 {
1024 execsql {
1025 SELECT group_concat(NULL,t1) FROM tbl1
1026 }
1027} {{}}
1028do_test func-24.5 {
1029 execsql {
1030 SELECT group_concat(t1,NULL) FROM tbl1
1031 }
1032} {thisprogramisfreesoftware}
drh2dca8682008-03-21 17:13:13 +00001033do_test func-24.6 {
1034 execsql {
1035 SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
1036 }
1037} {BEGIN-this,program,is,free,software}
drh07d31172009-02-02 21:57:05 +00001038
1039# Ticket #3179: Make sure aggregate functions can take many arguments.
1040# None of the built-in aggregates do this, so use the md5sum() from the
1041# test extensions.
1042#
drh3780b5d2008-06-19 18:39:11 +00001043unset -nocomplain midargs
drha2baf3a2008-06-18 15:34:09 +00001044set midargs {}
drh3780b5d2008-06-19 18:39:11 +00001045unset -nocomplain midres
drha2baf3a2008-06-18 15:34:09 +00001046set midres {}
drh3780b5d2008-06-19 18:39:11 +00001047unset -nocomplain result
drh07d31172009-02-02 21:57:05 +00001048for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
drha2baf3a2008-06-18 15:34:09 +00001049 append midargs ,'/$i'
1050 append midres /$i
drh07d31172009-02-02 21:57:05 +00001051 set result [md5 \
1052 "this${midres}program${midres}is${midres}free${midres}software${midres}"]
1053 set sql "SELECT md5sum(t1$midargs) FROM tbl1"
drha2baf3a2008-06-18 15:34:09 +00001054 do_test func-24.7.$i {
1055 db eval $::sql
1056 } $result
1057}
drhade86482007-11-28 22:36:40 +00001058
drh8dc09a02009-04-15 15:16:53 +00001059# Ticket #3806. If the initial string in a group_concat is an empty
1060# string, the separate that follows should still be present.
1061#
1062do_test func-24.8 {
1063 execsql {
1064 SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
1065 }
1066} {,program,is,free,software}
1067do_test func-24.9 {
1068 execsql {
1069 SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
1070 }
1071} {,,,,software}
1072
drh191b54c2008-04-15 12:14:21 +00001073# Use the test_isolation function to make sure that type conversions
1074# on function arguments do not effect subsequent arguments.
1075#
1076do_test func-25.1 {
1077 execsql {SELECT test_isolation(t1,t1) FROM tbl1}
1078} {this program is free software}
1079
drh24b58dd2008-07-07 14:50:14 +00001080# Try to misuse the sqlite3_create_function() interface. Verify that
1081# errors are returned.
1082#
1083do_test func-26.1 {
1084 abuse_create_function db
1085} {}
1086
1087# The previous test (func-26.1) registered a function with a very long
1088# function name that takes many arguments and always returns NULL. Verify
1089# that this function works correctly.
1090#
1091do_test func-26.2 {
1092 set a {}
1093 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
1094 lappend a $i
1095 }
1096 db eval "
1097 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 ,]);
1098 "
1099} {{}}
1100do_test func-26.3 {
1101 set a {}
1102 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
1103 lappend a $i
1104 }
1105 catchsql "
1106 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 ,]);
1107 "
1108} {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}}
1109do_test func-26.4 {
1110 set a {}
1111 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
1112 lappend a $i
1113 }
1114 catchsql "
1115 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 ,]);
1116 "
1117} {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()}}
1118do_test func-26.5 {
1119 catchsql "
1120 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);
1121 "
1122} {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}}
1123do_test func-26.6 {
1124 catchsql "
1125 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);
1126 "
1127} {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}}
1128
drhdfbc3a82009-01-31 22:28:48 +00001129do_test func-27.1 {
1130 catchsql {SELECT coalesce()}
1131} {1 {wrong number of arguments to function coalesce()}}
1132do_test func-27.2 {
1133 catchsql {SELECT coalesce(1)}
1134} {1 {wrong number of arguments to function coalesce()}}
1135do_test func-27.3 {
1136 catchsql {SELECT coalesce(1,2)}
1137} {0 1}
1138
drh5708d2d2005-06-22 10:53:59 +00001139finish_test