blob: ccdda0cd8aad9aa5392e574a16d8d02898fda6dc [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#
drhff6e9112000-08-28 16:21:58 +000014
15set testdir [file dirname $argv0]
16source $testdir/tester.tcl
17
18# Create a table to work with.
19#
drhff6e9112000-08-28 16:21:58 +000020do_test func-0.0 {
drh297ecf12001-04-05 15:57:13 +000021 execsql {CREATE TABLE tbl1(t1 text)}
22 foreach word {this program is free software} {
23 execsql "INSERT INTO tbl1 VALUES('$word')"
24 }
drhff6e9112000-08-28 16:21:58 +000025 execsql {SELECT t1 FROM tbl1 ORDER BY t1}
26} {free is program software this}
drh832508b2002-03-02 17:04:07 +000027do_test func-0.1 {
28 execsql {
29 CREATE TABLE t2(a);
30 INSERT INTO t2 VALUES(1);
31 INSERT INTO t2 VALUES(NULL);
32 INSERT INTO t2 VALUES(345);
33 INSERT INTO t2 VALUES(NULL);
34 INSERT INTO t2 VALUES(67890);
35 SELECT * FROM t2;
36 }
37} {1 {} 345 {} 67890}
drhff6e9112000-08-28 16:21:58 +000038
39# Check out the length() function
40#
41do_test func-1.0 {
42 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
43} {4 2 7 8 4}
44do_test func-1.1 {
45 set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
46 lappend r $msg
drh89425d52002-02-28 03:04:48 +000047} {1 {wrong number of arguments to function length()}}
drhff6e9112000-08-28 16:21:58 +000048do_test func-1.2 {
49 set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
50 lappend r $msg
drh89425d52002-02-28 03:04:48 +000051} {1 {wrong number of arguments to function length()}}
drhff6e9112000-08-28 16:21:58 +000052do_test func-1.3 {
53 execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1)
54 ORDER BY length(t1)}
55} {2 1 4 2 7 1 8 1}
drh832508b2002-03-02 17:04:07 +000056do_test func-1.4 {
drhbb113512002-05-27 01:04:51 +000057 execsql {SELECT coalesce(length(a),-1) FROM t2}
58} {1 -1 3 -1 5}
drhff6e9112000-08-28 16:21:58 +000059
60# Check out the substr() function
61#
62do_test func-2.0 {
63 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
64} {fr is pr so th}
65do_test func-2.1 {
66 execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1}
67} {r s r o h}
68do_test func-2.2 {
69 execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1}
70} {ee {} ogr ftw is}
71do_test func-2.3 {
72 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
73} {e s m e s}
74do_test func-2.4 {
75 execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1}
76} {e s m e s}
77do_test func-2.5 {
78 execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1}
79} {e i a r i}
80do_test func-2.6 {
81 execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1}
82} {ee is am re is}
83do_test func-2.7 {
84 execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1}
85} {fr {} gr wa th}
86do_test func-2.8 {
87 execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)}
88} {this software free program is}
drh832508b2002-03-02 17:04:07 +000089do_test func-2.9 {
90 execsql {SELECT substr(a,1,1) FROM t2}
91} {1 {} 3 {} 6}
92do_test func-2.10 {
93 execsql {SELECT substr(a,2,2) FROM t2}
94} {{} {} 45 {} 78}
drhff6e9112000-08-28 16:21:58 +000095
drhdf014892004-06-02 00:41:09 +000096# Only do the following tests if TCL has UTF-8 capabilities
drh297ecf12001-04-05 15:57:13 +000097#
drhdf014892004-06-02 00:41:09 +000098if {"\u1234"!="u1234"} {
drh297ecf12001-04-05 15:57:13 +000099
100# Put some UTF-8 characters in the database
101#
102do_test func-3.0 {
103 execsql {DELETE FROM tbl1}
104 foreach word "contains UTF-8 characters hi\u1234ho" {
105 execsql "INSERT INTO tbl1 VALUES('$word')"
106 }
107 execsql {SELECT t1 FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000108} "UTF-8 characters contains hi\u1234ho"
drh297ecf12001-04-05 15:57:13 +0000109do_test func-3.1 {
110 execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000111} {5 10 8 5}
drh297ecf12001-04-05 15:57:13 +0000112do_test func-3.2 {
113 execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000114} {UT ch co hi}
drh297ecf12001-04-05 15:57:13 +0000115do_test func-3.3 {
116 execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000117} "UTF cha con hi\u1234"
drh297ecf12001-04-05 15:57:13 +0000118do_test func-3.4 {
119 execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000120} "TF ha on i\u1234"
drh297ecf12001-04-05 15:57:13 +0000121do_test func-3.5 {
122 execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000123} "TF- har ont i\u1234h"
drh297ecf12001-04-05 15:57:13 +0000124do_test func-3.6 {
125 execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000126} "F- ar nt \u1234h"
drh297ecf12001-04-05 15:57:13 +0000127do_test func-3.7 {
128 execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000129} "-8 ra ta ho"
drh297ecf12001-04-05 15:57:13 +0000130do_test func-3.8 {
131 execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000132} "8 s s o"
drh297ecf12001-04-05 15:57:13 +0000133do_test func-3.9 {
134 execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000135} "F- er in \u1234h"
drh297ecf12001-04-05 15:57:13 +0000136do_test func-3.10 {
137 execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1}
drha9e99ae2002-08-13 23:02:57 +0000138} "TF- ter ain i\u1234h"
drh832508b2002-03-02 17:04:07 +0000139do_test func-3.99 {
140 execsql {DELETE FROM tbl1}
141 foreach word {this program is free software} {
142 execsql "INSERT INTO tbl1 VALUES('$word')"
143 }
144 execsql {SELECT t1 FROM tbl1}
145} {this program is free software}
drh297ecf12001-04-05 15:57:13 +0000146
drhdf014892004-06-02 00:41:09 +0000147} ;# End \u1234!=u1234
drh297ecf12001-04-05 15:57:13 +0000148
drhbf4133c2001-10-13 02:59:08 +0000149# Test the abs() and round() functions.
150#
shanefbd60f82009-02-04 03:59:25 +0000151ifcapable !floatingpoint {
152 do_test func-4.1 {
153 execsql {
154 CREATE TABLE t1(a,b,c);
155 INSERT INTO t1 VALUES(1,2,3);
156 INSERT INTO t1 VALUES(2,12345678901234,-1234567890);
157 INSERT INTO t1 VALUES(3,-2,-5);
158 }
159 catchsql {SELECT abs(a,b) FROM t1}
160 } {1 {wrong number of arguments to function abs()}}
161}
162ifcapable floatingpoint {
163 do_test func-4.1 {
164 execsql {
165 CREATE TABLE t1(a,b,c);
166 INSERT INTO t1 VALUES(1,2,3);
167 INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
168 INSERT INTO t1 VALUES(3,-2,-5);
169 }
170 catchsql {SELECT abs(a,b) FROM t1}
171 } {1 {wrong number of arguments to function abs()}}
172}
drhbf4133c2001-10-13 02:59:08 +0000173do_test func-4.2 {
174 catchsql {SELECT abs() FROM t1}
drh89425d52002-02-28 03:04:48 +0000175} {1 {wrong number of arguments to function abs()}}
shanefbd60f82009-02-04 03:59:25 +0000176ifcapable floatingpoint {
177 do_test func-4.3 {
178 catchsql {SELECT abs(b) FROM t1 ORDER BY a}
179 } {0 {2 1.2345678901234 2}}
180 do_test func-4.4 {
181 catchsql {SELECT abs(c) FROM t1 ORDER BY a}
182 } {0 {3 12345.6789 5}}
183}
184ifcapable !floatingpoint {
185 if {[working_64bit_int]} {
186 do_test func-4.3 {
187 catchsql {SELECT abs(b) FROM t1 ORDER BY a}
188 } {0 {2 12345678901234 2}}
189 }
190 do_test func-4.4 {
191 catchsql {SELECT abs(c) FROM t1 ORDER BY a}
192 } {0 {3 1234567890 5}}
193}
drh832508b2002-03-02 17:04:07 +0000194do_test func-4.4.1 {
195 execsql {SELECT abs(a) FROM t2}
196} {1 {} 345 {} 67890}
197do_test func-4.4.2 {
198 execsql {SELECT abs(t1) FROM tbl1}
drh92febd92004-08-20 18:34:20 +0000199} {0.0 0.0 0.0 0.0 0.0}
drhbf4133c2001-10-13 02:59:08 +0000200
shanefbd60f82009-02-04 03:59:25 +0000201ifcapable floatingpoint {
202 do_test func-4.5 {
203 catchsql {SELECT round(a,b,c) FROM t1}
204 } {1 {wrong number of arguments to function round()}}
205 do_test func-4.6 {
206 catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
207 } {0 {-2.0 1.23 2.0}}
208 do_test func-4.7 {
209 catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
210 } {0 {2.0 1.0 -2.0}}
211 do_test func-4.8 {
212 catchsql {SELECT round(c) FROM t1 ORDER BY a}
213 } {0 {3.0 -12346.0 -5.0}}
214 do_test func-4.9 {
215 catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
216 } {0 {3.0 -12345.68 -5.0}}
217 do_test func-4.10 {
218 catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a}
219 } {0 {x3.0y x-12345.68y x-5.0y}}
220 do_test func-4.11 {
221 catchsql {SELECT round() FROM t1 ORDER BY a}
222 } {1 {wrong number of arguments to function round()}}
223 do_test func-4.12 {
224 execsql {SELECT coalesce(round(a,2),'nil') FROM t2}
225 } {1.0 nil 345.0 nil 67890.0}
226 do_test func-4.13 {
227 execsql {SELECT round(t1,2) FROM tbl1}
228 } {0.0 0.0 0.0 0.0 0.0}
229 do_test func-4.14 {
230 execsql {SELECT typeof(round(5.1,1));}
231 } {real}
232 do_test func-4.15 {
233 execsql {SELECT typeof(round(5.1));}
234 } {real}
235 do_test func-4.16 {
236 catchsql {SELECT round(b,2.0) FROM t1 ORDER BY b}
237 } {0 {-2.0 1.23 2.0}}
shaneh4a0b43c2010-02-16 22:00:35 +0000238 # Verify some values reported on the mailing list.
239 # Some of these fail on MSVC builds with 64-bit
240 # long doubles, but not on GCC builds with 80-bit
241 # long doubles.
242 for {set i 1} {$i<999} {incr i} {
243 set x1 [expr 40222.0 + $i + 0.5]
244 set x2 [expr 40223.0 + $i]
245 do_test func-4.17.$i {
246 execsql {SELECT round($x1);}
247 } $x2
248 }
249 do_test func-4.18 {
250 execsql {SELECT round(41051.5);}
251 } {41052.0}
252 do_test func-4.19 {
253 execsql {SELECT round(41224.5);}
254 } {41225.0}
255 do_test func-4.20 {
256 execsql {SELECT round(40223.4999999999);}
257 } {40223.0}
258 do_test func-4.21 {
259 execsql {SELECT round(40224.4999999999);}
260 } {40224.0}
261 do_test func-4.22 {
262 execsql {SELECT round(40225.4999999999);}
263 } {40225.0}
264 for {set i 1} {$i<10} {incr i} {
265 do_test func-4.23.$i {
266 execsql {SELECT round(40223.4999999999,$i);}
267 } {40223.5}
268 do_test func-4.24.$i {
269 execsql {SELECT round(40224.4999999999,$i);}
270 } {40224.5}
271 do_test func-4.25.$i {
272 execsql {SELECT round(40225.4999999999,$i);}
273 } {40225.5}
274 }
275 for {set i 10} {$i<32} {incr i} {
276 do_test func-4.26.$i {
277 execsql {SELECT round(40223.4999999999,$i);}
278 } {40223.4999999999}
279 do_test func-4.27.$i {
280 execsql {SELECT round(40224.4999999999,$i);}
281 } {40224.4999999999}
282 do_test func-4.28.$i {
283 execsql {SELECT round(40225.4999999999,$i);}
284 } {40225.4999999999}
285 }
286 do_test func-4.29 {
287 execsql {SELECT round(1234567890.5);}
288 } {1234567891.0}
289 do_test func-4.30 {
290 execsql {SELECT round(12345678901.5);}
291 } {12345678902.0}
292 do_test func-4.31 {
293 execsql {SELECT round(123456789012.5);}
294 } {123456789013.0}
295 do_test func-4.32 {
296 execsql {SELECT round(1234567890123.5);}
297 } {1234567890124.0}
298 do_test func-4.33 {
299 execsql {SELECT round(12345678901234.5);}
300 } {12345678901235.0}
301 do_test func-4.34 {
302 execsql {SELECT round(1234567890123.35,1);}
303 } {1234567890123.4}
304 do_test func-4.35 {
305 execsql {SELECT round(1234567890123.445,2);}
306 } {1234567890123.45}
307 do_test func-4.36 {
308 execsql {SELECT round(99999999999994.5);}
309 } {99999999999995.0}
310 do_test func-4.37 {
311 execsql {SELECT round(9999999999999.55,1);}
312 } {9999999999999.6}
313 do_test func-4.38 {
314 execsql {SELECT round(9999999999999.555,2);}
315 } {9999999999999.56}
shanefbd60f82009-02-04 03:59:25 +0000316}
drh832508b2002-03-02 17:04:07 +0000317
318# Test the upper() and lower() functions
319#
320do_test func-5.1 {
321 execsql {SELECT upper(t1) FROM tbl1}
322} {THIS PROGRAM IS FREE SOFTWARE}
323do_test func-5.2 {
324 execsql {SELECT lower(upper(t1)) FROM tbl1}
325} {this program is free software}
326do_test func-5.3 {
327 execsql {SELECT upper(a), lower(a) FROM t2}
328} {1 1 {} {} 345 345 {} {} 67890 67890}
danielk19777de68a02007-05-07 16:58:02 +0000329ifcapable !icu {
330 do_test func-5.4 {
331 catchsql {SELECT upper(a,5) FROM t2}
332 } {1 {wrong number of arguments to function upper()}}
333}
drh832508b2002-03-02 17:04:07 +0000334do_test func-5.5 {
335 catchsql {SELECT upper(*) FROM t2}
336} {1 {wrong number of arguments to function upper()}}
337
drha9f9d1c2002-06-29 02:20:08 +0000338# Test the coalesce() and nullif() functions
drh832508b2002-03-02 17:04:07 +0000339#
340do_test func-6.1 {
341 execsql {SELECT coalesce(a,'xyz') FROM t2}
342} {1 xyz 345 xyz 67890}
343do_test func-6.2 {
344 execsql {SELECT coalesce(upper(a),'nil') FROM t2}
345} {1 nil 345 nil 67890}
drha9f9d1c2002-06-29 02:20:08 +0000346do_test func-6.3 {
347 execsql {SELECT coalesce(nullif(1,1),'nil')}
348} {nil}
349do_test func-6.4 {
350 execsql {SELECT coalesce(nullif(1,2),'nil')}
351} {1}
352do_test func-6.5 {
353 execsql {SELECT coalesce(nullif(1,NULL),'nil')}
354} {1}
355
drh832508b2002-03-02 17:04:07 +0000356
drh6ed41ad2002-04-06 14:10:47 +0000357# Test the last_insert_rowid() function
358#
359do_test func-7.1 {
360 execsql {SELECT last_insert_rowid()}
361} [db last_insert_rowid]
362
drh739105c2002-05-29 23:22:23 +0000363# Tests for aggregate functions and how they handle NULLs.
364#
shanefbd60f82009-02-04 03:59:25 +0000365ifcapable floatingpoint {
366 do_test func-8.1 {
367 ifcapable explain {
368 execsql {EXPLAIN SELECT sum(a) FROM t2;}
369 }
370 execsql {
371 SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
372 }
373 } {68236 3 22745.33 1 67890 5}
374}
375ifcapable !floatingpoint {
376 do_test func-8.1 {
377 ifcapable explain {
378 execsql {EXPLAIN SELECT sum(a) FROM t2;}
379 }
380 execsql {
381 SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2;
382 }
383 } {68236 3 22745.0 1 67890 5}
384}
drha9f9d1c2002-06-29 02:20:08 +0000385do_test func-8.2 {
386 execsql {
387 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
388 }
389} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
danielk197753c0f742005-03-29 03:10:59 +0000390
391ifcapable tempdb {
392 do_test func-8.3 {
393 execsql {
394 CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
395 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
396 }
397 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
398} else {
399 do_test func-8.3 {
400 execsql {
401 CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
402 SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
403 }
404 } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
405}
danielk19773aeab9e2004-06-24 00:20:04 +0000406do_test func-8.4 {
407 execsql {
408 SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
409 }
410} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
danielk1977de3e41e2008-08-04 03:51:24 +0000411ifcapable compound {
412 do_test func-8.5 {
413 execsql {
414 SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
415 UNION ALL SELECT -9223372036854775807)
416 }
417 } {0}
418 do_test func-8.6 {
419 execsql {
420 SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
421 UNION ALL SELECT -9223372036854775807)
422 }
423 } {integer}
424 do_test func-8.7 {
425 execsql {
426 SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
427 UNION ALL SELECT -9223372036854775807)
428 }
429 } {real}
shanefbd60f82009-02-04 03:59:25 +0000430ifcapable floatingpoint {
danielk1977de3e41e2008-08-04 03:51:24 +0000431 do_test func-8.8 {
432 execsql {
433 SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
434 UNION ALL SELECT -9223372036850000000)
435 }
436 } {1}
437}
shanefbd60f82009-02-04 03:59:25 +0000438ifcapable !floatingpoint {
439 do_test func-8.8 {
440 execsql {
441 SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x
442 UNION ALL SELECT -9223372036850000000)
443 }
444 } {1}
445}
446}
drh739105c2002-05-29 23:22:23 +0000447
drha9f9d1c2002-06-29 02:20:08 +0000448# How do you test the random() function in a meaningful, deterministic way?
449#
450do_test func-9.1 {
451 execsql {
452 SELECT random() is not null;
453 }
454} {1}
drh63cf66f2007-01-29 15:50:05 +0000455do_test func-9.2 {
456 execsql {
457 SELECT typeof(random());
458 }
459} {integer}
460do_test func-9.3 {
461 execsql {
drh137c7282007-01-29 17:58:28 +0000462 SELECT randomblob(32) is not null;
drh63cf66f2007-01-29 15:50:05 +0000463 }
464} {1}
465do_test func-9.4 {
466 execsql {
drh137c7282007-01-29 17:58:28 +0000467 SELECT typeof(randomblob(32));
drh63cf66f2007-01-29 15:50:05 +0000468 }
drh137c7282007-01-29 17:58:28 +0000469} {blob}
drh63cf66f2007-01-29 15:50:05 +0000470do_test func-9.5 {
471 execsql {
drh137c7282007-01-29 17:58:28 +0000472 SELECT length(randomblob(32)), length(randomblob(-5)),
473 length(randomblob(2000))
drh63cf66f2007-01-29 15:50:05 +0000474 }
drh137c7282007-01-29 17:58:28 +0000475} {32 1 2000}
drh63cf66f2007-01-29 15:50:05 +0000476
drh137c7282007-01-29 17:58:28 +0000477# The "hex()" function was added in order to be able to render blobs
478# generated by randomblob(). So this seems like a good place to test
479# hex().
480#
danielk19774152e672007-09-12 17:01:45 +0000481ifcapable bloblit {
482 do_test func-9.10 {
483 execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
484 } {00112233445566778899AABBCCDDEEFF}
485}
drh056c8f72007-05-15 18:35:21 +0000486set encoding [db one {PRAGMA encoding}]
487if {$encoding=="UTF-16le"} {
488 do_test func-9.11-utf16le {
489 execsql {SELECT hex(replace('abcdefg','ef','12'))}
490 } {6100620063006400310032006700}
491 do_test func-9.12-utf16le {
492 execsql {SELECT hex(replace('abcdefg','','12'))}
drha605fe82009-02-01 18:08:40 +0000493 } {6100620063006400650066006700}
drh056c8f72007-05-15 18:35:21 +0000494 do_test func-9.13-utf16le {
495 execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
496 } {610061006100610061006100620063006400650066006700}
497} elseif {$encoding=="UTF-8"} {
498 do_test func-9.11-utf8 {
499 execsql {SELECT hex(replace('abcdefg','ef','12'))}
500 } {61626364313267}
501 do_test func-9.12-utf8 {
502 execsql {SELECT hex(replace('abcdefg','','12'))}
drha605fe82009-02-01 18:08:40 +0000503 } {61626364656667}
drh056c8f72007-05-15 18:35:21 +0000504 do_test func-9.13-utf8 {
505 execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
506 } {616161616161626364656667}
507}
508
drh6cbe1f12002-07-01 00:31:36 +0000509# Use the "sqlite_register_test_function" TCL command which is part of
510# the text fixture in order to verify correct operation of some of
511# the user-defined SQL function APIs that are not used by the built-in
512# functions.
513#
drhdddca282006-01-03 00:33:50 +0000514set ::DB [sqlite3_connection_pointer db]
drh6cbe1f12002-07-01 00:31:36 +0000515sqlite_register_test_function $::DB testfunc
516do_test func-10.1 {
517 catchsql {
518 SELECT testfunc(NULL,NULL);
519 }
danielk19776d88bad2004-05-27 14:23:36 +0000520} {1 {first argument should be one of: int int64 string double null value}}
drh6cbe1f12002-07-01 00:31:36 +0000521do_test func-10.2 {
522 execsql {
523 SELECT testfunc(
524 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
525 'int', 1234
526 );
527 }
528} {1234}
529do_test func-10.3 {
530 execsql {
531 SELECT testfunc(
532 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
533 'string', NULL
534 );
535 }
536} {{}}
shanefbd60f82009-02-04 03:59:25 +0000537
538ifcapable floatingpoint {
539 do_test func-10.4 {
540 execsql {
541 SELECT testfunc(
542 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
543 'double', 1.234
544 );
545 }
546 } {1.234}
547 do_test func-10.5 {
548 execsql {
549 SELECT testfunc(
550 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
551 'int', 1234,
552 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
553 'string', NULL,
554 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
555 'double', 1.234,
556 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
557 'int', 1234,
558 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
559 'string', NULL,
560 'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
561 'double', 1.234
562 );
563 }
564 } {1.234}
565}
drh6cbe1f12002-07-01 00:31:36 +0000566
drh647cb0e2002-11-04 19:32:25 +0000567# Test the built-in sqlite_version(*) SQL function.
568#
569do_test func-11.1 {
570 execsql {
571 SELECT sqlite_version(*);
572 }
drhef4ac8f2004-06-19 00:16:31 +0000573} [sqlite3 -version]
drh647cb0e2002-11-04 19:32:25 +0000574
drhef4ac8f2004-06-19 00:16:31 +0000575# Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
danielk19773f6b0872004-06-17 05:36:44 +0000576# etc. are called. These tests use two special user-defined functions
577# (implemented in func.c) only available in test builds.
578#
579# Function test_destructor() takes one argument and returns a copy of the
580# text form of that argument. A destructor is associated with the return
581# value. Function test_destructor_count() returns the number of outstanding
582# destructor calls for values returned by test_destructor().
583#
drhda84ca82008-03-19 16:35:24 +0000584if {[db eval {PRAGMA encoding}]=="UTF-8"} {
585 do_test func-12.1-utf8 {
586 execsql {
587 SELECT test_destructor('hello world'), test_destructor_count();
588 }
589 } {{hello world} 1}
590} else {
shane2a5fc4d2008-07-31 01:47:11 +0000591 ifcapable {utf16} {
592 do_test func-12.1-utf16 {
593 execsql {
594 SELECT test_destructor16('hello world'), test_destructor_count();
595 }
596 } {{hello world} 1}
drhda84ca82008-03-19 16:35:24 +0000597 }
drhda84ca82008-03-19 16:35:24 +0000598}
danielk1977d8123362004-06-12 09:25:12 +0000599do_test func-12.2 {
600 execsql {
601 SELECT test_destructor_count();
602 }
603} {0}
604do_test func-12.3 {
605 execsql {
drh2dcef112008-01-12 19:03:48 +0000606 SELECT test_destructor('hello')||' world'
danielk1977d8123362004-06-12 09:25:12 +0000607 }
drh2dcef112008-01-12 19:03:48 +0000608} {{hello world}}
danielk1977d8123362004-06-12 09:25:12 +0000609do_test func-12.4 {
610 execsql {
611 SELECT test_destructor_count();
612 }
613} {0}
614do_test func-12.5 {
615 execsql {
616 CREATE TABLE t4(x);
617 INSERT INTO t4 VALUES(test_destructor('hello'));
618 INSERT INTO t4 VALUES(test_destructor('world'));
619 SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
620 }
621} {hello world}
622do_test func-12.6 {
623 execsql {
624 SELECT test_destructor_count();
625 }
626} {0}
danielk19773f6b0872004-06-17 05:36:44 +0000627do_test func-12.7 {
628 execsql {
629 DROP TABLE t4;
630 }
631} {}
632
drha4e5d582007-10-20 15:41:57 +0000633
danielk19773f6b0872004-06-17 05:36:44 +0000634# Test that the auxdata API for scalar functions works. This test uses
635# a special user-defined function only available in test builds,
636# test_auxdata(). Function test_auxdata() takes any number of arguments.
637do_test func-13.1 {
638 execsql {
639 SELECT test_auxdata('hello world');
640 }
641} {0}
danielk1977ece80f12004-06-23 01:05:26 +0000642
danielk19773f6b0872004-06-17 05:36:44 +0000643do_test func-13.2 {
644 execsql {
645 CREATE TABLE t4(a, b);
646 INSERT INTO t4 VALUES('abc', 'def');
647 INSERT INTO t4 VALUES('ghi', 'jkl');
648 }
649} {}
650do_test func-13.3 {
651 execsql {
652 SELECT test_auxdata('hello world') FROM t4;
653 }
654} {0 1}
655do_test func-13.4 {
656 execsql {
657 SELECT test_auxdata('hello world', 123) FROM t4;
658 }
659} {{0 0} {1 1}}
660do_test func-13.5 {
661 execsql {
662 SELECT test_auxdata('hello world', a) FROM t4;
663 }
664} {{0 0} {1 0}}
665do_test func-13.6 {
666 execsql {
667 SELECT test_auxdata('hello'||'world', a) FROM t4;
668 }
669} {{0 0} {1 0}}
670
671# Test that auxilary data is preserved between calls for SQL variables.
672do_test func-13.7 {
drhdddca282006-01-03 00:33:50 +0000673 set DB [sqlite3_connection_pointer db]
danielk19773f6b0872004-06-17 05:36:44 +0000674 set sql "SELECT test_auxdata( ? , a ) FROM t4;"
675 set STMT [sqlite3_prepare $DB $sql -1 TAIL]
drh10dfbbb2008-04-16 12:58:53 +0000676 sqlite3_bind_text $STMT 1 hello\000 -1
danielk19773f6b0872004-06-17 05:36:44 +0000677 set res [list]
678 while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
679 lappend res [sqlite3_column_text $STMT 0]
680 }
681 lappend res [sqlite3_finalize $STMT]
682} {{0 0} {1 0} SQLITE_OK}
danielk1977d8123362004-06-12 09:25:12 +0000683
danielk1977312d6b32004-06-29 13:18:23 +0000684# Make sure that a function with a very long name is rejected
685do_test func-14.1 {
686 catch {
687 db function [string repeat X 254] {return "hello"}
688 }
689} {0}
690do_test func-14.2 {
691 catch {
692 db function [string repeat X 256] {return "hello"}
693 }
694} {1}
695
danielk197701427a62005-01-11 13:02:33 +0000696do_test func-15.1 {
drh00e087b2008-04-10 17:14:07 +0000697 catchsql {select test_error(NULL)}
drh90669c12006-01-20 15:45:36 +0000698} {1 {}}
drh00e087b2008-04-10 17:14:07 +0000699do_test func-15.2 {
700 catchsql {select test_error('this is the error message')}
701} {1 {this is the error message}}
702do_test func-15.3 {
703 catchsql {select test_error('this is the error message',12)}
704} {1 {this is the error message}}
705do_test func-15.4 {
706 db errorcode
707} {12}
danielk197701427a62005-01-11 13:02:33 +0000708
danielk1977576ec6b2005-01-21 11:55:25 +0000709# Test the quote function for BLOB and NULL values.
710do_test func-16.1 {
711 execsql {
712 CREATE TABLE tbl2(a, b);
713 }
714 set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
715 sqlite3_bind_blob $::STMT 1 abc 3
716 sqlite3_step $::STMT
717 sqlite3_finalize $::STMT
718 execsql {
719 SELECT quote(a), quote(b) FROM tbl2;
720 }
721} {X'616263' NULL}
722
drh2501eb12005-08-12 23:20:53 +0000723# Correctly handle function error messages that include %. Ticket #1354
724#
725do_test func-17.1 {
726 proc testfunc1 args {error "Error %d with %s percents %p"}
727 db function testfunc1 ::testfunc1
728 catchsql {
729 SELECT testfunc1(1,2,3);
730 }
731} {1 {Error %d with %s percents %p}}
732
drh3d1d95e2005-09-08 10:37:01 +0000733# The SUM function should return integer results when all inputs are integer.
734#
735do_test func-18.1 {
736 execsql {
737 CREATE TABLE t5(x);
738 INSERT INTO t5 VALUES(1);
739 INSERT INTO t5 VALUES(-99);
740 INSERT INTO t5 VALUES(10000);
741 SELECT sum(x) FROM t5;
742 }
743} {9902}
shanefbd60f82009-02-04 03:59:25 +0000744ifcapable floatingpoint {
745 do_test func-18.2 {
746 execsql {
747 INSERT INTO t5 VALUES(0.0);
748 SELECT sum(x) FROM t5;
749 }
750 } {9902.0}
751}
danielk1977576ec6b2005-01-21 11:55:25 +0000752
drhc2bd9132005-09-08 20:37:43 +0000753# The sum of nothing is NULL. But the sum of all NULLs is NULL.
drh3f219f42005-09-08 19:45:57 +0000754#
drh76c730c2006-02-09 17:47:42 +0000755# The TOTAL of nothing is 0.0.
756#
drh3f219f42005-09-08 19:45:57 +0000757do_test func-18.3 {
758 execsql {
759 DELETE FROM t5;
drh76c730c2006-02-09 17:47:42 +0000760 SELECT sum(x), total(x) FROM t5;
drh3f219f42005-09-08 19:45:57 +0000761 }
drh76c730c2006-02-09 17:47:42 +0000762} {{} 0.0}
drh3f219f42005-09-08 19:45:57 +0000763do_test func-18.4 {
764 execsql {
765 INSERT INTO t5 VALUES(NULL);
drh76c730c2006-02-09 17:47:42 +0000766 SELECT sum(x), total(x) FROM t5
drh3f219f42005-09-08 19:45:57 +0000767 }
drh76c730c2006-02-09 17:47:42 +0000768} {{} 0.0}
drh3f219f42005-09-08 19:45:57 +0000769do_test func-18.5 {
770 execsql {
771 INSERT INTO t5 VALUES(NULL);
drh76c730c2006-02-09 17:47:42 +0000772 SELECT sum(x), total(x) FROM t5
drh3f219f42005-09-08 19:45:57 +0000773 }
drh76c730c2006-02-09 17:47:42 +0000774} {{} 0.0}
drh3f219f42005-09-08 19:45:57 +0000775do_test func-18.6 {
776 execsql {
777 INSERT INTO t5 VALUES(123);
drh76c730c2006-02-09 17:47:42 +0000778 SELECT sum(x), total(x) FROM t5
drh3f219f42005-09-08 19:45:57 +0000779 }
drh76c730c2006-02-09 17:47:42 +0000780} {123 123.0}
drh5708d2d2005-06-22 10:53:59 +0000781
drh8c08e862006-02-11 17:34:00 +0000782# Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
783# an error. The non-standard TOTAL() function continues to give a helpful
784# result.
drhfc6ad392006-02-09 13:38:19 +0000785#
786do_test func-18.10 {
787 execsql {
788 CREATE TABLE t6(x INTEGER);
789 INSERT INTO t6 VALUES(1);
790 INSERT INTO t6 VALUES(1<<62);
791 SELECT sum(x) - ((1<<62)+1) from t6;
792 }
793} 0
drh76c730c2006-02-09 17:47:42 +0000794do_test func-18.11 {
795 execsql {
796 SELECT typeof(sum(x)) FROM t6
797 }
798} integer
shanefbd60f82009-02-04 03:59:25 +0000799ifcapable floatingpoint {
800 do_test func-18.12 {
801 catchsql {
802 INSERT INTO t6 VALUES(1<<62);
803 SELECT sum(x) - ((1<<62)*2.0+1) from t6;
804 }
805 } {1 {integer overflow}}
806 do_test func-18.13 {
807 execsql {
808 SELECT total(x) - ((1<<62)*2.0+1) FROM t6
809 }
810 } 0.0
811}
812ifcapable !floatingpoint {
813 do_test func-18.12 {
814 catchsql {
815 INSERT INTO t6 VALUES(1<<62);
816 SELECT sum(x) - ((1<<62)*2+1) from t6;
817 }
818 } {1 {integer overflow}}
819 do_test func-18.13 {
820 execsql {
821 SELECT total(x) - ((1<<62)*2+1) FROM t6
822 }
823 } 0.0
824}
825if {[working_64bit_int]} {
826 do_test func-18.14 {
827 execsql {
828 SELECT sum(-9223372036854775805);
829 }
830 } -9223372036854775805
831}
danielk19774b2688a2006-06-20 11:01:07 +0000832ifcapable compound&&subquery {
833
drh8c08e862006-02-11 17:34:00 +0000834do_test func-18.15 {
835 catchsql {
836 SELECT sum(x) FROM
837 (SELECT 9223372036854775807 AS x UNION ALL
838 SELECT 10 AS x);
839 }
840} {1 {integer overflow}}
shanefbd60f82009-02-04 03:59:25 +0000841if {[working_64bit_int]} {
842 do_test func-18.16 {
843 catchsql {
844 SELECT sum(x) FROM
845 (SELECT 9223372036854775807 AS x UNION ALL
846 SELECT -10 AS x);
847 }
848 } {0 9223372036854775797}
849 do_test func-18.17 {
850 catchsql {
851 SELECT sum(x) FROM
852 (SELECT -9223372036854775807 AS x UNION ALL
853 SELECT 10 AS x);
854 }
855 } {0 -9223372036854775797}
856}
drh8c08e862006-02-11 17:34:00 +0000857do_test func-18.18 {
858 catchsql {
859 SELECT sum(x) FROM
860 (SELECT -9223372036854775807 AS x UNION ALL
861 SELECT -10 AS x);
862 }
863} {1 {integer overflow}}
864do_test func-18.19 {
865 catchsql {
866 SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
867 }
868} {0 -1}
869do_test func-18.20 {
870 catchsql {
871 SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
872 }
873} {0 1}
874do_test func-18.21 {
875 catchsql {
876 SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
877 }
878} {0 -1}
879do_test func-18.22 {
880 catchsql {
881 SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
882 }
883} {0 1}
drh76c730c2006-02-09 17:47:42 +0000884
danielk19774b2688a2006-06-20 11:01:07 +0000885} ;# ifcapable compound&&subquery
886
drh52fc8492006-02-23 21:43:55 +0000887# Integer overflow on abs()
888#
shanefbd60f82009-02-04 03:59:25 +0000889if {[working_64bit_int]} {
890 do_test func-18.31 {
891 catchsql {
892 SELECT abs(-9223372036854775807);
893 }
894 } {0 9223372036854775807}
895}
drh52fc8492006-02-23 21:43:55 +0000896do_test func-18.32 {
897 catchsql {
898 SELECT abs(-9223372036854775807-1);
899 }
900} {1 {integer overflow}}
901
drh7f375902006-06-13 17:38:59 +0000902# The MATCH function exists but is only a stub and always throws an error.
903#
904do_test func-19.1 {
905 execsql {
906 SELECT match(a,b) FROM t1 WHERE 0;
907 }
908} {}
909do_test func-19.2 {
910 catchsql {
911 SELECT 'abc' MATCH 'xyz';
912 }
drhb7481e72006-09-16 21:45:14 +0000913} {1 {unable to use function MATCH in the requested context}}
drh7f375902006-06-13 17:38:59 +0000914do_test func-19.3 {
915 catchsql {
916 SELECT 'abc' NOT MATCH 'xyz';
917 }
drhb7481e72006-09-16 21:45:14 +0000918} {1 {unable to use function MATCH in the requested context}}
drh7f375902006-06-13 17:38:59 +0000919do_test func-19.4 {
920 catchsql {
921 SELECT match(1,2,3);
922 }
923} {1 {wrong number of arguments to function match()}}
drh76c730c2006-02-09 17:47:42 +0000924
drhbdf67e02006-08-19 11:34:01 +0000925# Soundex tests.
926#
927if {![catch {db eval {SELECT soundex('hello')}}]} {
928 set i 0
929 foreach {name sdx} {
930 euler E460
931 EULER E460
932 Euler E460
933 ellery E460
934 gauss G200
935 ghosh G200
936 hilbert H416
937 Heilbronn H416
938 knuth K530
939 kant K530
940 Lloyd L300
941 LADD L300
942 Lukasiewicz L222
943 Lissajous L222
944 A A000
945 12345 ?000
946 } {
947 incr i
948 do_test func-20.$i {
949 execsql {SELECT soundex($name)}
950 } $sdx
951 }
952}
953
drh26b6d902007-03-17 13:27:54 +0000954# Tests of the REPLACE function.
955#
956do_test func-21.1 {
957 catchsql {
958 SELECT replace(1,2);
959 }
960} {1 {wrong number of arguments to function replace()}}
961do_test func-21.2 {
962 catchsql {
963 SELECT replace(1,2,3,4);
964 }
965} {1 {wrong number of arguments to function replace()}}
966do_test func-21.3 {
967 execsql {
968 SELECT typeof(replace("This is the main test string", NULL, "ALT"));
969 }
970} {null}
971do_test func-21.4 {
972 execsql {
973 SELECT typeof(replace(NULL, "main", "ALT"));
974 }
975} {null}
976do_test func-21.5 {
977 execsql {
978 SELECT typeof(replace("This is the main test string", "main", NULL));
979 }
980} {null}
981do_test func-21.6 {
982 execsql {
983 SELECT replace("This is the main test string", "main", "ALT");
984 }
985} {{This is the ALT test string}}
986do_test func-21.7 {
987 execsql {
988 SELECT replace("This is the main test string", "main", "larger-main");
989 }
990} {{This is the larger-main test string}}
991do_test func-21.8 {
992 execsql {
993 SELECT replace("aaaaaaa", "a", "0123456789");
994 }
995} {0123456789012345678901234567890123456789012345678901234567890123456789}
996
danielk19774152e672007-09-12 17:01:45 +0000997ifcapable tclvar {
998 do_test func-21.9 {
999 # Attempt to exploit a buffer-overflow that at one time existed
1000 # in the REPLACE function.
1001 set ::str "[string repeat A 29998]CC[string repeat A 35537]"
1002 set ::rep [string repeat B 65536]
1003 execsql {
1004 SELECT LENGTH(REPLACE($::str, 'C', $::rep));
1005 }
1006 } [expr 29998 + 2*65536 + 35537]
1007}
danielk197717374e82007-05-08 14:39:04 +00001008
drh309b3382007-03-17 17:52:42 +00001009# Tests for the TRIM, LTRIM and RTRIM functions.
1010#
1011do_test func-22.1 {
1012 catchsql {SELECT trim(1,2,3)}
1013} {1 {wrong number of arguments to function trim()}}
1014do_test func-22.2 {
1015 catchsql {SELECT ltrim(1,2,3)}
1016} {1 {wrong number of arguments to function ltrim()}}
1017do_test func-22.3 {
1018 catchsql {SELECT rtrim(1,2,3)}
1019} {1 {wrong number of arguments to function rtrim()}}
1020do_test func-22.4 {
1021 execsql {SELECT trim(' hi ');}
1022} {hi}
1023do_test func-22.5 {
1024 execsql {SELECT ltrim(' hi ');}
1025} {{hi }}
1026do_test func-22.6 {
1027 execsql {SELECT rtrim(' hi ');}
1028} {{ hi}}
1029do_test func-22.7 {
1030 execsql {SELECT trim(' hi ','xyz');}
1031} {{ hi }}
1032do_test func-22.8 {
1033 execsql {SELECT ltrim(' hi ','xyz');}
1034} {{ hi }}
1035do_test func-22.9 {
1036 execsql {SELECT rtrim(' hi ','xyz');}
1037} {{ hi }}
1038do_test func-22.10 {
1039 execsql {SELECT trim('xyxzy hi zzzy','xyz');}
1040} {{ hi }}
1041do_test func-22.11 {
1042 execsql {SELECT ltrim('xyxzy hi zzzy','xyz');}
1043} {{ hi zzzy}}
1044do_test func-22.12 {
1045 execsql {SELECT rtrim('xyxzy hi zzzy','xyz');}
1046} {{xyxzy hi }}
1047do_test func-22.13 {
1048 execsql {SELECT trim(' hi ','');}
1049} {{ hi }}
drh4e05c832007-05-11 01:44:50 +00001050if {[db one {PRAGMA encoding}]=="UTF-8"} {
1051 do_test func-22.14 {
1052 execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
1053 } {F48FBFBF6869}
1054 do_test func-22.15 {
1055 execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
1056 x'6162e1bfbfc280f48fbfbf'))}
1057 } {6869}
1058 do_test func-22.16 {
1059 execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
1060 } {CEB2CEB3}
1061}
drh309b3382007-03-17 17:52:42 +00001062do_test func-22.20 {
1063 execsql {SELECT typeof(trim(NULL));}
1064} {null}
1065do_test func-22.21 {
1066 execsql {SELECT typeof(trim(NULL,'xyz'));}
1067} {null}
1068do_test func-22.22 {
1069 execsql {SELECT typeof(trim('hello',NULL));}
1070} {null}
drh26b6d902007-03-17 13:27:54 +00001071
danielk1977fa18bec2007-09-03 11:04:22 +00001072# This is to test the deprecated sqlite3_aggregate_count() API.
1073#
shaneeec556d2008-10-12 00:27:53 +00001074ifcapable deprecated {
1075 do_test func-23.1 {
1076 sqlite3_create_aggregate db
1077 execsql {
1078 SELECT legacy_count() FROM t6;
1079 }
1080 } {3}
1081}
danielk1977fa18bec2007-09-03 11:04:22 +00001082
drhade86482007-11-28 22:36:40 +00001083# The group_concat() function.
1084#
1085do_test func-24.1 {
1086 execsql {
1087 SELECT group_concat(t1) FROM tbl1
1088 }
1089} {this,program,is,free,software}
1090do_test func-24.2 {
1091 execsql {
1092 SELECT group_concat(t1,' ') FROM tbl1
1093 }
1094} {{this program is free software}}
1095do_test func-24.3 {
1096 execsql {
1097 SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
1098 }
1099} {{this 2 program 3 is 4 free 5 software}}
1100do_test func-24.4 {
1101 execsql {
1102 SELECT group_concat(NULL,t1) FROM tbl1
1103 }
1104} {{}}
1105do_test func-24.5 {
1106 execsql {
1107 SELECT group_concat(t1,NULL) FROM tbl1
1108 }
1109} {thisprogramisfreesoftware}
drh2dca8682008-03-21 17:13:13 +00001110do_test func-24.6 {
1111 execsql {
1112 SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
1113 }
1114} {BEGIN-this,program,is,free,software}
drh07d31172009-02-02 21:57:05 +00001115
1116# Ticket #3179: Make sure aggregate functions can take many arguments.
1117# None of the built-in aggregates do this, so use the md5sum() from the
1118# test extensions.
1119#
drh3780b5d2008-06-19 18:39:11 +00001120unset -nocomplain midargs
drha2baf3a2008-06-18 15:34:09 +00001121set midargs {}
drh3780b5d2008-06-19 18:39:11 +00001122unset -nocomplain midres
drha2baf3a2008-06-18 15:34:09 +00001123set midres {}
drh3780b5d2008-06-19 18:39:11 +00001124unset -nocomplain result
drh07d31172009-02-02 21:57:05 +00001125for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
drha2baf3a2008-06-18 15:34:09 +00001126 append midargs ,'/$i'
1127 append midres /$i
drh07d31172009-02-02 21:57:05 +00001128 set result [md5 \
1129 "this${midres}program${midres}is${midres}free${midres}software${midres}"]
1130 set sql "SELECT md5sum(t1$midargs) FROM tbl1"
drha2baf3a2008-06-18 15:34:09 +00001131 do_test func-24.7.$i {
1132 db eval $::sql
1133 } $result
1134}
drhade86482007-11-28 22:36:40 +00001135
drh8dc09a02009-04-15 15:16:53 +00001136# Ticket #3806. If the initial string in a group_concat is an empty
drh8bfd7192009-06-19 16:44:41 +00001137# string, the separator that follows should still be present.
drh8dc09a02009-04-15 15:16:53 +00001138#
1139do_test func-24.8 {
1140 execsql {
1141 SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
1142 }
1143} {,program,is,free,software}
1144do_test func-24.9 {
1145 execsql {
1146 SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
1147 }
1148} {,,,,software}
1149
drh8bfd7192009-06-19 16:44:41 +00001150# Ticket #3923. Initial empty strings have a separator. But initial
1151# NULLs do not.
1152#
1153do_test func-24.10 {
1154 execsql {
1155 SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1
1156 }
1157} {program,is,free,software}
1158do_test func-24.11 {
1159 execsql {
1160 SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1
1161 }
1162} {software}
1163do_test func-24.12 {
1164 execsql {
1165 SELECT group_concat(CASE t1 WHEN 'this' THEN ''
1166 WHEN 'program' THEN null ELSE t1 END) FROM tbl1
1167 }
1168} {,is,free,software}
1169
1170
drh191b54c2008-04-15 12:14:21 +00001171# Use the test_isolation function to make sure that type conversions
1172# on function arguments do not effect subsequent arguments.
1173#
1174do_test func-25.1 {
1175 execsql {SELECT test_isolation(t1,t1) FROM tbl1}
1176} {this program is free software}
1177
drh24b58dd2008-07-07 14:50:14 +00001178# Try to misuse the sqlite3_create_function() interface. Verify that
1179# errors are returned.
1180#
1181do_test func-26.1 {
1182 abuse_create_function db
1183} {}
1184
1185# The previous test (func-26.1) registered a function with a very long
1186# function name that takes many arguments and always returns NULL. Verify
1187# that this function works correctly.
1188#
1189do_test func-26.2 {
1190 set a {}
1191 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
1192 lappend a $i
1193 }
1194 db eval "
1195 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 ,]);
1196 "
1197} {{}}
1198do_test func-26.3 {
1199 set a {}
1200 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
1201 lappend a $i
1202 }
1203 catchsql "
1204 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 ,]);
1205 "
1206} {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}}
1207do_test func-26.4 {
1208 set a {}
1209 for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
1210 lappend a $i
1211 }
1212 catchsql "
1213 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 ,]);
1214 "
1215} {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()}}
1216do_test func-26.5 {
1217 catchsql "
1218 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);
1219 "
1220} {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}}
1221do_test func-26.6 {
1222 catchsql "
1223 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);
1224 "
1225} {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}}
1226
drhdfbc3a82009-01-31 22:28:48 +00001227do_test func-27.1 {
1228 catchsql {SELECT coalesce()}
1229} {1 {wrong number of arguments to function coalesce()}}
1230do_test func-27.2 {
1231 catchsql {SELECT coalesce(1)}
1232} {1 {wrong number of arguments to function coalesce()}}
1233do_test func-27.3 {
1234 catchsql {SELECT coalesce(1,2)}
1235} {0 1}
1236
drhfeb306f2009-08-18 16:05:46 +00001237# Ticket 2d401a94287b5
1238# Unknown function in a DEFAULT expression causes a segfault.
1239#
1240do_test func-28.1 {
1241 db eval {
1242 CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1)));
1243 }
1244 catchsql {
1245 INSERT INTO t28(x) VALUES(1);
1246 }
1247} {1 {unknown function: nosuchfunc()}}
1248
drh5708d2d2005-06-22 10:53:59 +00001249finish_test