Merge branch 'prerelease' of ssh://git.zetetic.net/sqlcipher into prerelease
[sqlcipher.git] / test / func.test
blobca1027f5083f266020bc2f58b57f48ee5968c0bf
1 # 2001 September 15
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
6 #    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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library.  The
12 # focus of this file is testing built-in functions.
15 set testdir [file dirname $argv0]
16 source $testdir/tester.tcl
17 set testprefix func
19 # Create a table to work with.
21 do_test func-0.0 {
22   execsql {CREATE TABLE tbl1(t1 text)}
23   foreach word {this program is free software} {
24     execsql "INSERT INTO tbl1 VALUES('$word')"
25   }
26   execsql {SELECT t1 FROM tbl1 ORDER BY t1}
27 } {free is program software this}
28 do_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}
40 # Check out the length() function
42 do_test func-1.0 {
43   execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
44 } {4 2 7 8 4}
45 do_test func-1.1 {
46   set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
47   lappend r $msg
48 } {1 {wrong number of arguments to function length()}}
49 do_test func-1.2 {
50   set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
51   lappend r $msg
52 } {1 {wrong number of arguments to function length()}}
53 do_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}
57 do_test func-1.4 {
58   execsql {SELECT coalesce(length(a),-1) FROM t2}
59 } {1 -1 3 -1 5}
61 # Check out the substr() function
63 do_test func-2.0 {
64   execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
65 } {fr is pr so th}
66 do_test func-2.1 {
67   execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1}
68 } {r s r o h}
69 do_test func-2.2 {
70   execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1}
71 } {ee {} ogr ftw is}
72 do_test func-2.3 {
73   execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
74 } {e s m e s}
75 do_test func-2.4 {
76   execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1}
77 } {e s m e s}
78 do_test func-2.5 {
79   execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1}
80 } {e i a r i}
81 do_test func-2.6 {
82   execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1}
83 } {ee is am re is}
84 do_test func-2.7 {
85   execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1}
86 } {fr {} gr wa th}
87 do_test func-2.8 {
88   execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)}
89 } {this software free program is}
90 do_test func-2.9 {
91   execsql {SELECT substr(a,1,1) FROM t2}
92 } {1 {} 3 {} 6}
93 do_test func-2.10 {
94   execsql {SELECT substr(a,2,2) FROM t2}
95 } {{} {} 45 {} 78}
97 # Only do the following tests if TCL has UTF-8 capabilities
99 if {"\u1234"!="u1234"} {
101 # Put some UTF-8 characters in the database
103 do_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}
109 } "UTF-8 characters contains hi\u1234ho"
110 do_test func-3.1 {
111   execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
112 } {5 10 8 5}
113 do_test func-3.2 {
114   execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
115 } {UT ch co hi}
116 do_test func-3.3 {
117   execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1}
118 } "UTF cha con hi\u1234"
119 do_test func-3.4 {
120   execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1}
121 } "TF ha on i\u1234"
122 do_test func-3.5 {
123   execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1}
124 } "TF- har ont i\u1234h"
125 do_test func-3.6 {
126   execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1}
127 } "F- ar nt \u1234h"
128 do_test func-3.7 {
129   execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1}
130 } "-8 ra ta ho"
131 do_test func-3.8 {
132   execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
133 } "8 s s o"
134 do_test func-3.9 {
135   execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1}
136 } "F- er in \u1234h"
137 do_test func-3.10 {
138   execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1}
139 } "TF- ter ain i\u1234h"
140 do_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}
148 } ;# End \u1234!=u1234
150 # Test the abs() and round() functions.
152 ifcapable !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()}}
163 ifcapable 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()}}
174 do_test func-4.2 {
175   catchsql {SELECT abs() FROM t1}
176 } {1 {wrong number of arguments to function abs()}}
177 ifcapable 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}}
185 ifcapable !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}}
195 do_test func-4.4.1 {
196   execsql {SELECT abs(a) FROM t2}
197 } {1 {} 345 {} 67890}
198 do_test func-4.4.2 {
199   execsql {SELECT abs(t1) FROM tbl1}
200 } {0.0 0.0 0.0 0.0 0.0}
202 ifcapable 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   # Verify some values reported on the mailing list.
240   # Some of these fail on MSVC builds with 64-bit
241   # long doubles, but not on GCC builds with 80-bit
242   # long doubles.
243   for {set i 1} {$i<999} {incr i} {
244     set x1 [expr 40222.5 + $i]
245     set x2 [expr 40223.0 + $i]
246     do_test func-4.17.$i {
247       execsql {SELECT round($x1);}
248     } $x2
249   }
250   for {set i 1} {$i<999} {incr i} {
251     set x1 [expr 40222.05 + $i]
252     set x2 [expr 40222.10 + $i]
253     do_test func-4.18.$i {
254       execsql {SELECT round($x1,1);}
255     } $x2
256   }
257   do_test func-4.20 {
258     execsql {SELECT round(40223.4999999999);}
259   } {40223.0}
260   do_test func-4.21 {
261     execsql {SELECT round(40224.4999999999);}
262   } {40224.0}
263   do_test func-4.22 {
264     execsql {SELECT round(40225.4999999999);}
265   } {40225.0}
266   for {set i 1} {$i<10} {incr i} {
267     do_test func-4.23.$i {
268       execsql {SELECT round(40223.4999999999,$i);}
269     } {40223.5}
270     do_test func-4.24.$i {
271       execsql {SELECT round(40224.4999999999,$i);}
272     } {40224.5}
273     do_test func-4.25.$i {
274       execsql {SELECT round(40225.4999999999,$i);}
275     } {40225.5}
276   }
277   for {set i 10} {$i<32} {incr i} {
278     do_test func-4.26.$i {
279       execsql {SELECT round(40223.4999999999,$i);}
280     } {40223.4999999999}
281     do_test func-4.27.$i {
282       execsql {SELECT round(40224.4999999999,$i);}
283     } {40224.4999999999}
284     do_test func-4.28.$i {
285       execsql {SELECT round(40225.4999999999,$i);}
286     } {40225.4999999999}
287   }
288   do_test func-4.29 {
289     execsql {SELECT round(1234567890.5);}
290   } {1234567891.0}
291   do_test func-4.30 {
292     execsql {SELECT round(12345678901.5);}
293   } {12345678902.0}
294   do_test func-4.31 {
295     execsql {SELECT round(123456789012.5);}
296   } {123456789013.0}
297   do_test func-4.32 {
298     execsql {SELECT round(1234567890123.5);}
299   } {1234567890124.0}
300   do_test func-4.33 {
301     execsql {SELECT round(12345678901234.5);}
302   } {12345678901235.0}
303   do_test func-4.34 {
304     execsql {SELECT round(1234567890123.35,1);}
305   } {1234567890123.4}
306   do_test func-4.35 {
307     execsql {SELECT round(1234567890123.445,2);}
308   } {1234567890123.45}
309   do_test func-4.36 {
310     execsql {SELECT round(99999999999994.5);}
311   } {99999999999995.0}
312   do_test func-4.37 {
313     execsql {SELECT round(9999999999999.55,1);}
314   } {9999999999999.6}
315   do_test func-4.38 {
316     execsql {SELECT round(9999999999999.556,2);}
317   } {9999999999999.56}
318   do_test func-4.39 {
319     string tolower [db eval {SELECT round(1e500), round(-1e500);}]
320   } {inf -inf}
323 # Test the upper() and lower() functions
325 do_test func-5.1 {
326   execsql {SELECT upper(t1) FROM tbl1}
327 } {THIS PROGRAM IS FREE SOFTWARE}
328 do_test func-5.2 {
329   execsql {SELECT lower(upper(t1)) FROM tbl1}
330 } {this program is free software}
331 do_test func-5.3 {
332   execsql {SELECT upper(a), lower(a) FROM t2}
333 } {1 1 {} {} 345 345 {} {} 67890 67890}
334 ifcapable !icu {
335   do_test func-5.4 {
336     catchsql {SELECT upper(a,5) FROM t2}
337   } {1 {wrong number of arguments to function upper()}}
339 do_test func-5.5 {
340   catchsql {SELECT upper(*) FROM t2}
341 } {1 {wrong number of arguments to function upper()}}
343 # Test the coalesce() and nullif() functions
345 do_test func-6.1 {
346   execsql {SELECT coalesce(a,'xyz') FROM t2}
347 } {1 xyz 345 xyz 67890}
348 do_test func-6.2 {
349   execsql {SELECT coalesce(upper(a),'nil') FROM t2}
350 } {1 nil 345 nil 67890}
351 do_test func-6.3 {
352   execsql {SELECT coalesce(nullif(1,1),'nil')}
353 } {nil}
354 do_test func-6.4 {
355   execsql {SELECT coalesce(nullif(1,2),'nil')}
356 } {1}
357 do_test func-6.5 {
358   execsql {SELECT coalesce(nullif(1,NULL),'nil')}
359 } {1}
362 # Test the last_insert_rowid() function
364 do_test func-7.1 {
365   execsql {SELECT last_insert_rowid()}
366 } [db last_insert_rowid]
368 # Tests for aggregate functions and how they handle NULLs.
370 ifcapable floatingpoint {
371   do_test func-8.1 {
372     ifcapable explain {
373       execsql {EXPLAIN SELECT sum(a) FROM t2;}
374     }
375     execsql {
376       SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
377     }
378   } {68236 3 22745.33 1 67890 5}
380 ifcapable !floatingpoint {
381   do_test func-8.1 {
382     ifcapable explain {
383       execsql {EXPLAIN SELECT sum(a) FROM t2;}
384     }
385     execsql {
386       SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2;
387     }
388   } {68236 3 22745.0 1 67890 5}
390 do_test func-8.2 {
391   execsql {
392     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
393   }
394 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
396 ifcapable tempdb {
397   do_test func-8.3 {
398     execsql {
399       CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
400       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
401     }
402   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
403 } else {
404   do_test func-8.3 {
405     execsql {
406       CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
407       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
408     }
409   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
411 do_test func-8.4 {
412   execsql {
413     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
414   }
415 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
416 ifcapable compound {
417   do_test func-8.5 {
418     execsql {
419       SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
420                           UNION ALL SELECT -9223372036854775807)
421     }
422   } {0}
423   do_test func-8.6 {
424     execsql {
425       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
426                           UNION ALL SELECT -9223372036854775807)
427     }
428   } {integer}
429   do_test func-8.7 {
430     execsql {
431       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
432                           UNION ALL SELECT -9223372036854775807)
433     }
434   } {real}
435 ifcapable floatingpoint {
436   do_test func-8.8 {
437     execsql {
438       SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
439                           UNION ALL SELECT -9223372036850000000)
440     }
441   } {1}
443 ifcapable !floatingpoint {
444   do_test func-8.8 {
445     execsql {
446       SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x
447                           UNION ALL SELECT -9223372036850000000)
448     }
449   } {1}
453 # How do you test the random() function in a meaningful, deterministic way?
455 do_test func-9.1 {
456   execsql {
457     SELECT random() is not null;
458   }
459 } {1}
460 do_test func-9.2 {
461   execsql {
462     SELECT typeof(random());
463   }
464 } {integer}
465 do_test func-9.3 {
466   execsql {
467     SELECT randomblob(32) is not null;
468   }
469 } {1}
470 do_test func-9.4 {
471   execsql {
472     SELECT typeof(randomblob(32));
473   }
474 } {blob}
475 do_test func-9.5 {
476   execsql {
477     SELECT length(randomblob(32)), length(randomblob(-5)),
478            length(randomblob(2000))
479   }
480 } {32 1 2000}
482 # The "hex()" function was added in order to be able to render blobs
483 # generated by randomblob().  So this seems like a good place to test
484 # hex().
486 ifcapable bloblit {
487   do_test func-9.10 {
488     execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
489   } {00112233445566778899AABBCCDDEEFF}
491 set encoding [db one {PRAGMA encoding}]
492 if {$encoding=="UTF-16le"} {
493   do_test func-9.11-utf16le {
494     execsql {SELECT hex(replace('abcdefg','ef','12'))}
495   } {6100620063006400310032006700}
496   do_test func-9.12-utf16le {
497     execsql {SELECT hex(replace('abcdefg','','12'))}
498   } {6100620063006400650066006700}
499   do_test func-9.13-utf16le {
500     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
501   } {610061006100610061006100620063006400650066006700}
502 } elseif {$encoding=="UTF-8"} {
503   do_test func-9.11-utf8 {
504     execsql {SELECT hex(replace('abcdefg','ef','12'))}
505   } {61626364313267}
506   do_test func-9.12-utf8 {
507     execsql {SELECT hex(replace('abcdefg','','12'))}
508   } {61626364656667}
509   do_test func-9.13-utf8 {
510     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
511   } {616161616161626364656667}
513 do_execsql_test func-9.14 {
514   WITH RECURSIVE c(x) AS (
515      VALUES(1)
516      UNION ALL
517      SELECT x+1 FROM c WHERE x<1040
518   )
519   SELECT 
520     count(*),
521     sum(length(replace(printf('abc%.*cxyz',x,'m'),'m','nnnn'))-(6+x*4))
522   FROM c;
523 } {1040 0}
524   
525 # Use the "sqlite_register_test_function" TCL command which is part of
526 # the text fixture in order to verify correct operation of some of
527 # the user-defined SQL function APIs that are not used by the built-in
528 # functions.
530 set ::DB [sqlite3_connection_pointer db]
531 sqlite_register_test_function $::DB testfunc
532 do_test func-10.1 {
533   catchsql {
534     SELECT testfunc(NULL,NULL);
535   }
536 } {1 {first argument should be one of: int int64 string double null value}}
537 do_test func-10.2 {
538   execsql {
539     SELECT testfunc(
540      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
541      'int', 1234
542     );
543   }
544 } {1234}
545 do_test func-10.3 {
546   execsql {
547     SELECT testfunc(
548      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
549      'string', NULL
550     );
551   }
552 } {{}}
554 ifcapable floatingpoint {
555   do_test func-10.4 {
556     execsql {
557       SELECT testfunc(
558        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
559        'double', 1.234
560       );
561     }
562   } {1.234}
563   do_test func-10.5 {
564     execsql {
565       SELECT testfunc(
566        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
567        'int', 1234,
568        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
569        'string', NULL,
570        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
571        'double', 1.234,
572        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
573        'int', 1234,
574        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
575        'string', NULL,
576        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
577        'double', 1.234
578       );
579     }
580   } {1.234}
583 # Test the built-in sqlite_version(*) SQL function.
585 do_test func-11.1 {
586   execsql {
587     SELECT sqlite_version(*);
588   }
589 } [sqlite3 -version]
591 # Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
592 # etc. are called. These tests use two special user-defined functions
593 # (implemented in func.c) only available in test builds. 
595 # Function test_destructor() takes one argument and returns a copy of the
596 # text form of that argument. A destructor is associated with the return
597 # value. Function test_destructor_count() returns the number of outstanding
598 # destructor calls for values returned by test_destructor().
600 if {[db eval {PRAGMA encoding}]=="UTF-8"} {
601   do_test func-12.1-utf8 {
602     execsql {
603       SELECT test_destructor('hello world'), test_destructor_count();
604     }
605   } {{hello world} 1}
606 } else {
607     ifcapable {utf16} {
608       do_test func-12.1-utf16 {
609         execsql {
610           SELECT test_destructor16('hello world'), test_destructor_count();
611         }
612       } {{hello world} 1}
613     }
615 do_test func-12.2 {
616   execsql {
617     SELECT test_destructor_count();
618   }
619 } {0}
620 do_test func-12.3 {
621   execsql {
622     SELECT test_destructor('hello')||' world'
623   }
624 } {{hello world}}
625 do_test func-12.4 {
626   execsql {
627     SELECT test_destructor_count();
628   }
629 } {0}
630 do_test func-12.5 {
631   execsql {
632     CREATE TABLE t4(x);
633     INSERT INTO t4 VALUES(test_destructor('hello'));
634     INSERT INTO t4 VALUES(test_destructor('world'));
635     SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
636   }
637 } {hello world}
638 do_test func-12.6 {
639   execsql {
640     SELECT test_destructor_count();
641   }
642 } {0}
643 do_test func-12.7 {
644   execsql {
645     DROP TABLE t4;
646   }
647 } {}
650 # Test that the auxdata API for scalar functions works. This test uses
651 # a special user-defined function only available in test builds,
652 # test_auxdata(). Function test_auxdata() takes any number of arguments.
653 do_test func-13.1 {
654   execsql {
655     SELECT test_auxdata('hello world');
656   }
657 } {0}
659 do_test func-13.2 {
660   execsql {
661     CREATE TABLE t4(a, b);
662     INSERT INTO t4 VALUES('abc', 'def');
663     INSERT INTO t4 VALUES('ghi', 'jkl');
664   }
665 } {}
666 do_test func-13.3 {
667   execsql {
668     SELECT test_auxdata('hello world') FROM t4;
669   }
670 } {0 1}
671 do_test func-13.4 {
672   execsql {
673     SELECT test_auxdata('hello world', 123) FROM t4;
674   }
675 } {{0 0} {1 1}}
676 do_test func-13.5 {
677   execsql {
678     SELECT test_auxdata('hello world', a) FROM t4;
679   }
680 } {{0 0} {1 0}}
681 do_test func-13.6 {
682   execsql {
683     SELECT test_auxdata('hello'||'world', a) FROM t4;
684   }
685 } {{0 0} {1 0}}
687 # Test that auxilary data is preserved between calls for SQL variables.
688 do_test func-13.7 {
689   set DB [sqlite3_connection_pointer db]
690   set sql "SELECT test_auxdata( ? , a ) FROM t4;"
691   set STMT [sqlite3_prepare $DB $sql -1 TAIL]
692   sqlite3_bind_text $STMT 1 hello\000 -1
693   set res [list]
694   while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
695     lappend res [sqlite3_column_text $STMT 0]
696   }
697   lappend res [sqlite3_finalize $STMT]
698 } {{0 0} {1 0} SQLITE_OK}
700 # Test that auxiliary data is discarded when a statement is reset.
701 do_execsql_test 13.8.1 {
702   SELECT test_auxdata('constant') FROM t4;
703 } {0 1}
704 do_execsql_test 13.8.2 {
705   SELECT test_auxdata('constant') FROM t4;
706 } {0 1}
707 db cache flush
708 do_execsql_test 13.8.3 {
709   SELECT test_auxdata('constant') FROM t4;
710 } {0 1}
711 set V "one"
712 do_execsql_test 13.8.4 {
713   SELECT test_auxdata($V), $V FROM t4;
714 } {0 one 1 one}
715 set V "two"
716 do_execsql_test 13.8.5 {
717   SELECT test_auxdata($V), $V FROM t4;
718 } {0 two 1 two}
719 db cache flush
720 set V "three"
721 do_execsql_test 13.8.6 {
722   SELECT test_auxdata($V), $V FROM t4;
723 } {0 three 1 three}
726 # Make sure that a function with a very long name is rejected
727 do_test func-14.1 {
728   catch {
729     db function [string repeat X 254] {return "hello"}
730   } 
731 } {0}
732 do_test func-14.2 {
733   catch {
734     db function [string repeat X 256] {return "hello"}
735   }
736 } {1}
738 do_test func-15.1 {
739   catchsql {select test_error(NULL)}
740 } {1 {}}
741 do_test func-15.2 {
742   catchsql {select test_error('this is the error message')}
743 } {1 {this is the error message}}
744 do_test func-15.3 {
745   catchsql {select test_error('this is the error message',12)}
746 } {1 {this is the error message}}
747 do_test func-15.4 {
748   db errorcode
749 } {12}
751 # Test the quote function for BLOB and NULL values.
752 do_test func-16.1 {
753   execsql {
754     CREATE TABLE tbl2(a, b);
755   }
756   set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
757   sqlite3_bind_blob $::STMT 1 abc 3
758   sqlite3_step $::STMT
759   sqlite3_finalize $::STMT
760   execsql {
761     SELECT quote(a), quote(b) FROM tbl2;
762   }
763 } {X'616263' NULL}
765 # Correctly handle function error messages that include %.  Ticket #1354
767 do_test func-17.1 {
768   proc testfunc1 args {error "Error %d with %s percents %p"}
769   db function testfunc1 ::testfunc1
770   catchsql {
771     SELECT testfunc1(1,2,3);
772   }
773 } {1 {Error %d with %s percents %p}}
775 # The SUM function should return integer results when all inputs are integer.
777 do_test func-18.1 {
778   execsql {
779     CREATE TABLE t5(x);
780     INSERT INTO t5 VALUES(1);
781     INSERT INTO t5 VALUES(-99);
782     INSERT INTO t5 VALUES(10000);
783     SELECT sum(x) FROM t5;
784   }
785 } {9902}
786 ifcapable floatingpoint {
787   do_test func-18.2 {
788     execsql {
789       INSERT INTO t5 VALUES(0.0);
790       SELECT sum(x) FROM t5;
791     }
792   } {9902.0}
795 # The sum of nothing is NULL.  But the sum of all NULLs is NULL.
797 # The TOTAL of nothing is 0.0.
799 do_test func-18.3 {
800   execsql {
801     DELETE FROM t5;
802     SELECT sum(x), total(x) FROM t5;
803   }
804 } {{} 0.0}
805 do_test func-18.4 {
806   execsql {
807     INSERT INTO t5 VALUES(NULL);
808     SELECT sum(x), total(x) FROM t5
809   }
810 } {{} 0.0}
811 do_test func-18.5 {
812   execsql {
813     INSERT INTO t5 VALUES(NULL);
814     SELECT sum(x), total(x) FROM t5
815   }
816 } {{} 0.0}
817 do_test func-18.6 {
818   execsql {
819     INSERT INTO t5 VALUES(123);
820     SELECT sum(x), total(x) FROM t5
821   }
822 } {123 123.0}
824 # Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
825 # an error. The non-standard TOTAL() function continues to give a helpful
826 # result.
828 do_test func-18.10 {
829   execsql {
830     CREATE TABLE t6(x INTEGER);
831     INSERT INTO t6 VALUES(1);
832     INSERT INTO t6 VALUES(1<<62);
833     SELECT sum(x) - ((1<<62)+1) from t6;
834   }
835 } 0
836 do_test func-18.11 {
837   execsql {
838     SELECT typeof(sum(x)) FROM t6
839   }
840 } integer
841 ifcapable floatingpoint {
842   do_test func-18.12 {
843     catchsql {
844       INSERT INTO t6 VALUES(1<<62);
845       SELECT sum(x) - ((1<<62)*2.0+1) from t6;
846     }
847   } {1 {integer overflow}}
848   do_test func-18.13 {
849     execsql {
850       SELECT total(x) - ((1<<62)*2.0+1) FROM t6
851     }
852   } 0.0
854 ifcapable !floatingpoint {
855   do_test func-18.12 {
856     catchsql {
857       INSERT INTO t6 VALUES(1<<62);
858       SELECT sum(x) - ((1<<62)*2+1) from t6;
859     }
860   } {1 {integer overflow}}
861   do_test func-18.13 {
862     execsql {
863       SELECT total(x) - ((1<<62)*2+1) FROM t6
864     }
865   } 0.0
867 if {[working_64bit_int]} {
868   do_test func-18.14 {
869     execsql {
870       SELECT sum(-9223372036854775805);
871     }
872   } -9223372036854775805
874 ifcapable compound&&subquery {
876 do_test func-18.15 {
877   catchsql {
878     SELECT sum(x) FROM 
879        (SELECT 9223372036854775807 AS x UNION ALL
880         SELECT 10 AS x);
881   }
882 } {1 {integer overflow}}
883 if {[working_64bit_int]} {
884   do_test func-18.16 {
885     catchsql {
886       SELECT sum(x) FROM 
887          (SELECT 9223372036854775807 AS x UNION ALL
888           SELECT -10 AS x);
889     }
890   } {0 9223372036854775797}
891   do_test func-18.17 {
892     catchsql {
893       SELECT sum(x) FROM 
894          (SELECT -9223372036854775807 AS x UNION ALL
895           SELECT 10 AS x);
896     }
897   } {0 -9223372036854775797}
899 do_test func-18.18 {
900   catchsql {
901     SELECT sum(x) FROM 
902        (SELECT -9223372036854775807 AS x UNION ALL
903         SELECT -10 AS x);
904   }
905 } {1 {integer overflow}}
906 do_test func-18.19 {
907   catchsql {
908     SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
909   }
910 } {0 -1}
911 do_test func-18.20 {
912   catchsql {
913     SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
914   }
915 } {0 1}
916 do_test func-18.21 {
917   catchsql {
918     SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
919   }
920 } {0 -1}
921 do_test func-18.22 {
922   catchsql {
923     SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
924   }
925 } {0 1}
927 } ;# ifcapable compound&&subquery
929 # Integer overflow on abs()
931 if {[working_64bit_int]} {
932   do_test func-18.31 {
933     catchsql {
934       SELECT abs(-9223372036854775807);
935     }
936   } {0 9223372036854775807}
938 do_test func-18.32 {
939   catchsql {
940     SELECT abs(-9223372036854775807-1);
941   }
942 } {1 {integer overflow}}
944 # The MATCH function exists but is only a stub and always throws an error.
946 do_test func-19.1 {
947   execsql {
948     SELECT match(a,b) FROM t1 WHERE 0;
949   }
950 } {}
951 do_test func-19.2 {
952   catchsql {
953     SELECT 'abc' MATCH 'xyz';
954   }
955 } {1 {unable to use function MATCH in the requested context}}
956 do_test func-19.3 {
957   catchsql {
958     SELECT 'abc' NOT MATCH 'xyz';
959   }
960 } {1 {unable to use function MATCH in the requested context}}
961 do_test func-19.4 {
962   catchsql {
963     SELECT match(1,2,3);
964   }
965 } {1 {wrong number of arguments to function match()}}
967 # Soundex tests.
969 if {![catch {db eval {SELECT soundex('hello')}}]} {
970   set i 0
971   foreach {name sdx} {
972     euler        E460
973     EULER        E460
974     Euler        E460
975     ellery       E460
976     gauss        G200
977     ghosh        G200
978     hilbert      H416
979     Heilbronn    H416
980     knuth        K530
981     kant         K530
982     Lloyd        L300
983     LADD         L300
984     Lukasiewicz  L222
985     Lissajous    L222
986     A            A000
987     12345        ?000
988   } {
989     incr i
990     do_test func-20.$i {
991       execsql {SELECT soundex($name)}
992     } $sdx
993   }
996 # Tests of the REPLACE function.
998 do_test func-21.1 {
999   catchsql {
1000     SELECT replace(1,2);
1001   }
1002 } {1 {wrong number of arguments to function replace()}}
1003 do_test func-21.2 {
1004   catchsql {
1005     SELECT replace(1,2,3,4);
1006   }
1007 } {1 {wrong number of arguments to function replace()}}
1008 do_test func-21.3 {
1009   execsql {
1010     SELECT typeof(replace("This is the main test string", NULL, "ALT"));
1011   }
1012 } {null}
1013 do_test func-21.4 {
1014   execsql {
1015     SELECT typeof(replace(NULL, "main", "ALT"));
1016   }
1017 } {null}
1018 do_test func-21.5 {
1019   execsql {
1020     SELECT typeof(replace("This is the main test string", "main", NULL));
1021   }
1022 } {null}
1023 do_test func-21.6 {
1024   execsql {
1025     SELECT replace("This is the main test string", "main", "ALT");
1026   }
1027 } {{This is the ALT test string}}
1028 do_test func-21.7 {
1029   execsql {
1030     SELECT replace("This is the main test string", "main", "larger-main");
1031   }
1032 } {{This is the larger-main test string}}
1033 do_test func-21.8 {
1034   execsql {
1035     SELECT replace("aaaaaaa", "a", "0123456789");
1036   }
1037 } {0123456789012345678901234567890123456789012345678901234567890123456789}
1039 ifcapable tclvar {
1040   do_test func-21.9 {
1041     # Attempt to exploit a buffer-overflow that at one time existed 
1042     # in the REPLACE function. 
1043     set ::str "[string repeat A 29998]CC[string repeat A 35537]"
1044     set ::rep [string repeat B 65536]
1045     execsql {
1046       SELECT LENGTH(REPLACE($::str, 'C', $::rep));
1047     }
1048   } [expr 29998 + 2*65536 + 35537]
1051 # Tests for the TRIM, LTRIM and RTRIM functions.
1053 do_test func-22.1 {
1054   catchsql {SELECT trim(1,2,3)}
1055 } {1 {wrong number of arguments to function trim()}}
1056 do_test func-22.2 {
1057   catchsql {SELECT ltrim(1,2,3)}
1058 } {1 {wrong number of arguments to function ltrim()}}
1059 do_test func-22.3 {
1060   catchsql {SELECT rtrim(1,2,3)}
1061 } {1 {wrong number of arguments to function rtrim()}}
1062 do_test func-22.4 {
1063   execsql {SELECT trim('  hi  ');}
1064 } {hi}
1065 do_test func-22.5 {
1066   execsql {SELECT ltrim('  hi  ');}
1067 } {{hi  }}
1068 do_test func-22.6 {
1069   execsql {SELECT rtrim('  hi  ');}
1070 } {{  hi}}
1071 do_test func-22.7 {
1072   execsql {SELECT trim('  hi  ','xyz');}
1073 } {{  hi  }}
1074 do_test func-22.8 {
1075   execsql {SELECT ltrim('  hi  ','xyz');}
1076 } {{  hi  }}
1077 do_test func-22.9 {
1078   execsql {SELECT rtrim('  hi  ','xyz');}
1079 } {{  hi  }}
1080 do_test func-22.10 {
1081   execsql {SELECT trim('xyxzy  hi  zzzy','xyz');}
1082 } {{  hi  }}
1083 do_test func-22.11 {
1084   execsql {SELECT ltrim('xyxzy  hi  zzzy','xyz');}
1085 } {{  hi  zzzy}}
1086 do_test func-22.12 {
1087   execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
1088 } {{xyxzy  hi  }}
1089 do_test func-22.13 {
1090   execsql {SELECT trim('  hi  ','');}
1091 } {{  hi  }}
1092 if {[db one {PRAGMA encoding}]=="UTF-8"} {
1093   do_test func-22.14 {
1094     execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
1095   } {F48FBFBF6869}
1096   do_test func-22.15 {
1097     execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
1098                              x'6162e1bfbfc280f48fbfbf'))}
1099   } {6869}
1100   do_test func-22.16 {
1101     execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
1102   } {CEB2CEB3}
1104 do_test func-22.20 {
1105   execsql {SELECT typeof(trim(NULL));}
1106 } {null}
1107 do_test func-22.21 {
1108   execsql {SELECT typeof(trim(NULL,'xyz'));}
1109 } {null}
1110 do_test func-22.22 {
1111   execsql {SELECT typeof(trim('hello',NULL));}
1112 } {null}
1114 # 2021-06-15 - infinite loop due to unsigned character counter
1115 # overflow, reported by Zimuzo Ezeozue
1117 do_execsql_test func-22.23 {
1118   SELECT trim('xyzzy',x'c0808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080');
1119 } {xyzzy}
1121 # This is to test the deprecated sqlite3_aggregate_count() API.
1123 ifcapable deprecated {
1124   do_test func-23.1 {
1125     sqlite3_create_aggregate db
1126     execsql {
1127       SELECT legacy_count() FROM t6;
1128     }
1129   } {3}
1132 # The group_concat() function.
1134 do_test func-24.1 {
1135   execsql {
1136     SELECT group_concat(t1) FROM tbl1
1137   }
1138 } {this,program,is,free,software}
1139 do_test func-24.2 {
1140   execsql {
1141     SELECT group_concat(t1,' ') FROM tbl1
1142   }
1143 } {{this program is free software}}
1144 do_test func-24.3 {
1145   execsql {
1146     SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
1147   }
1148 } {{this 2 program 3 is 4 free 5 software}}
1149 do_test func-24.4 {
1150   execsql {
1151     SELECT group_concat(NULL,t1) FROM tbl1
1152   }
1153 } {{}}
1154 do_test func-24.5 {
1155   execsql {
1156     SELECT group_concat(t1,NULL) FROM tbl1
1157   }
1158 } {thisprogramisfreesoftware}
1159 do_test func-24.6 {
1160   execsql {
1161     SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
1162   }
1163 } {BEGIN-this,program,is,free,software}
1165 # Ticket #3179:  Make sure aggregate functions can take many arguments.
1166 # None of the built-in aggregates do this, so use the md5sum() from the
1167 # test extensions.
1169 unset -nocomplain midargs
1170 set midargs {}
1171 unset -nocomplain midres
1172 set midres {}
1173 unset -nocomplain result
1174 for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
1175   append midargs ,'/$i'
1176   append midres /$i
1177   set result [md5 \
1178      "this${midres}program${midres}is${midres}free${midres}software${midres}"]
1179   set sql "SELECT md5sum(t1$midargs) FROM tbl1"
1180   do_test func-24.7.$i {
1181      db eval $::sql
1182   } $result
1185 # Ticket #3806.  If the initial string in a group_concat is an empty
1186 # string, the separator that follows should still be present.
1188 do_test func-24.8 {
1189   execsql {
1190     SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
1191   }
1192 } {,program,is,free,software}
1193 do_test func-24.9 {
1194   execsql {
1195     SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
1196   }
1197 } {,,,,software}
1199 # Ticket #3923.  Initial empty strings have a separator.  But initial
1200 # NULLs do not.
1202 do_test func-24.10 {
1203   execsql {
1204     SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1
1205   }
1206 } {program,is,free,software}
1207 do_test func-24.11 {
1208   execsql {
1209    SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1
1210   }
1211 } {software}
1212 do_test func-24.12 {
1213   execsql {
1214     SELECT group_concat(CASE t1 WHEN 'this' THEN ''
1215                           WHEN 'program' THEN null ELSE t1 END) FROM tbl1
1216   }
1217 } {,is,free,software}
1218 # Tests to verify ticket http://www.sqlite.org/src/tktview/55746f9e65f8587c0
1219 do_test func-24.13 {
1220   execsql {
1221     SELECT typeof(group_concat(x)) FROM (SELECT '' AS x);
1222   }
1223 } {text}
1224 do_test func-24.14 {
1225   execsql {
1226     SELECT typeof(group_concat(x,''))
1227       FROM (SELECT '' AS x UNION ALL SELECT '');
1228   }
1229 } {text}
1232 # Use the test_isolation function to make sure that type conversions
1233 # on function arguments do not effect subsequent arguments.
1235 do_test func-25.1 {
1236   execsql {SELECT test_isolation(t1,t1) FROM tbl1}
1237 } {this program is free software}
1239 # Try to misuse the sqlite3_create_function() interface.  Verify that
1240 # errors are returned.
1242 do_test func-26.1 {
1243   abuse_create_function db
1244 } {}
1246 # The previous test (func-26.1) registered a function with a very long
1247 # function name that takes many arguments and always returns NULL.  Verify
1248 # that this function works correctly.
1250 do_test func-26.2 {
1251   set a {}
1252   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
1253     lappend a $i
1254   }
1255   db eval "
1256      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 ,]);
1257   "
1258 } {{}}
1259 do_test func-26.3 {
1260   set a {}
1261   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
1262     lappend a $i
1263   }
1264   catchsql "
1265      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 ,]);
1266   "
1267 } {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}}
1268 do_test func-26.4 {
1269   set a {}
1270   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
1271     lappend a $i
1272   }
1273   catchsql "
1274      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 ,]);
1275   "
1276 } {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()}}
1277 do_test func-26.5 {
1278   catchsql "
1279      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);
1280   "
1281 } {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}}
1282 do_test func-26.6 {
1283   catchsql "
1284      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);
1285   "
1286 } {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}}
1288 do_test func-27.1 {
1289   catchsql {SELECT coalesce()}
1290 } {1 {wrong number of arguments to function coalesce()}}
1291 do_test func-27.2 {
1292   catchsql {SELECT coalesce(1)}
1293 } {1 {wrong number of arguments to function coalesce()}}
1294 do_test func-27.3 {
1295   catchsql {SELECT coalesce(1,2)}
1296 } {0 1}
1298 # Ticket 2d401a94287b5
1299 # Unknown function in a DEFAULT expression causes a segfault.
1301 do_test func-28.1 {
1302   db eval {
1303     CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1)));
1304   }
1305   catchsql {
1306     INSERT INTO t28(x) VALUES(1);
1307   }
1308 } {1 {unknown function: nosuchfunc()}}
1310 # Verify that the length() and typeof() functions do not actually load
1311 # the content of their argument.
1313 do_test func-29.1 {
1314   db eval {
1315     CREATE TABLE t29(id INTEGER PRIMARY KEY, x, y);
1316     INSERT INTO t29 VALUES(1, 2, 3), (2, NULL, 4), (3, 4.5, 5);
1317     INSERT INTO t29 VALUES(4, randomblob(1000000), 6);
1318     INSERT INTO t29 VALUES(5, "hello", 7);
1319   }
1320   db close
1321   sqlite3 db test.db
1322   sqlite3_db_status db CACHE_MISS 1
1323   db eval {SELECT typeof(x), length(x), typeof(y) FROM t29 ORDER BY id}
1324 } {integer 1 integer null {} integer real 3 integer blob 1000000 integer text 5 integer}
1325 do_test func-29.2 {
1326   set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
1327   if {$x<5} {set x 1}
1328   set x
1329 } {1}
1330 do_test func-29.3 {
1331   db close
1332   sqlite3 db test.db
1333   sqlite3_db_status db CACHE_MISS 1
1334   db eval {SELECT typeof(+x) FROM t29 ORDER BY id}
1335 } {integer null real blob text}
1336 if {[permutation] != "mmap"} {
1337   ifcapable !direct_read {
1338     do_test func-29.4 {
1339       set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
1340       if {$x>100} {set x many}
1341       set x
1342     } {many}
1343   }
1345 do_test func-29.5 {
1346   db close
1347   sqlite3 db test.db
1348   sqlite3_db_status db CACHE_MISS 1
1349   db eval {SELECT sum(length(x)) FROM t29}
1350 } {1000009}
1351 do_test func-29.6 {
1352   set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
1353   if {$x<5} {set x 1}
1354   set x
1355 } {1}
1357 # The OP_Column opcode has an optimization that avoids loading content
1358 # for fields with content-length=0 when the content offset is on an overflow
1359 # page.  Make sure the optimization works.
1361 do_execsql_test func-29.10 {
1362   CREATE TABLE t29b(a,b,c,d,e,f,g,h,i);
1363   INSERT INTO t29b 
1364    VALUES(1, hex(randomblob(2000)), null, 0, 1, '', zeroblob(0),'x',x'01');
1365   SELECT typeof(c), typeof(d), typeof(e), typeof(f),
1366          typeof(g), typeof(h), typeof(i) FROM t29b;
1367 } {null integer integer text blob text blob}
1368 do_execsql_test func-29.11 {
1369   SELECT length(f), length(g), length(h), length(i) FROM t29b;
1370 } {0 0 1 1}
1371 do_execsql_test func-29.12 {
1372   SELECT quote(f), quote(g), quote(h), quote(i) FROM t29b;
1373 } {'' X'' 'x' X'01'}
1375 # EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric
1376 # unicode code point corresponding to the first character of the string
1377 # X.
1379 # EVIDENCE-OF: R-55469-62130 The char(X1,X2,...,XN) function returns a
1380 # string composed of characters having the unicode code point values of
1381 # integers X1 through XN, respectively.
1383 do_execsql_test func-30.1 {SELECT unicode('$');} 36
1384 do_execsql_test func-30.2 [subst {SELECT unicode('\u00A2');}] 162
1385 do_execsql_test func-30.3 [subst {SELECT unicode('\u20AC');}] 8364
1386 do_execsql_test func-30.4 {SELECT char(36,162,8364);} [subst {$\u00A2\u20AC}]
1388 for {set i 1} {$i<0xd800} {incr i 13} {
1389   do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
1391 for {set i 57344} {$i<=0xfffd} {incr i 17} {
1392   if {$i==0xfeff} continue
1393   do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
1395 for {set i 65536} {$i<=0x10ffff} {incr i 139} {
1396   do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
1399 # Test char().
1401 do_execsql_test func-31.1 { 
1402   SELECT char(), length(char()), typeof(char()) 
1403 } {{} 0 text}
1405 # sqlite3_value_frombind()
1407 do_execsql_test func-32.100 {
1408   SELECT test_frombind(1,2,3,4);
1409 } {0}
1410 do_execsql_test func-32.110 {
1411   SELECT test_frombind(1,2,?,4);
1412 } {4}
1413 do_execsql_test func-32.120 {
1414   SELECT test_frombind(1,(?),4,?+7);
1415 } {2}
1416 do_execsql_test func-32.130 {
1417   DROP TABLE IF EXISTS t1;
1418   CREATE TABLE t1(a,b,c,e,f);
1419   INSERT INTO t1 VALUES(1,2.5,'xyz',x'e0c1b2a3',null);
1420   SELECT test_frombind(a,b,c,e,f,$xyz) FROM t1;
1421 } {32}
1422 do_execsql_test func-32.140 {
1423   SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1;
1424 } {0}
1425 do_execsql_test func-32.150 {
1426   SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
1427 } {8}
1429 # 2019-08-15
1430 # Direct-only functions.
1432 proc testdirectonly {x} {return [expr {$x*2}]}
1433 do_test func-33.1 {
1434   db func testdirectonly -directonly testdirectonly
1435   db eval {SELECT testdirectonly(15)}
1436 } {30}
1437 do_catchsql_test func-33.2 {
1438   CREATE VIEW v33(y) AS SELECT testdirectonly(15);
1439   SELECT * FROM v33;
1440 } {1 {unsafe use of testdirectonly()}}
1441 do_execsql_test func-33.3 {
1442   SELECT * FROM (SELECT testdirectonly(15)) AS v33;
1443 } {30}
1444 do_execsql_test func-33.4 {
1445   WITH c(x) AS (SELECT testdirectonly(15))
1446   SELECT * FROM c;
1447 } {30}
1448 do_catchsql_test func-33.5 {
1449   WITH c(x) AS (SELECT * FROM v33)
1450   SELECT * FROM c;
1451 } {1 {unsafe use of testdirectonly()}}
1452 do_execsql_test func-33.10 {
1453   CREATE TABLE t33a(a,b);
1454   CREATE TABLE t33b(x,y);
1455   CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
1456     INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b);
1457   END;
1458 } {}
1459 do_catchsql_test func-33.11 {
1460   INSERT INTO t33a VALUES(1,2);
1461 } {1 {unsafe use of testdirectonly()}}
1463 ifcapable altertable {
1464 do_execsql_test func-33.20 {
1465   ALTER TABLE t33a RENAME COLUMN a TO aaa;
1466   SELECT sql FROM sqlite_master WHERE name='r1';
1467 } {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
1468     INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b);
1469   END}}
1472 # 2020-01-09 Yongheng fuzzer find
1473 # The bug is in the register-validity debug logic, not in the SQLite core
1474 # and as such it only impacts debug builds.  Release builds work fine.
1476 reset_db
1477 do_execsql_test func-34.10 {
1478   CREATE TABLE t1(a INT CHECK(
1479      datetime( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1480               10,11,12,13,14,15,16,17,18,19,
1481               20,21,22,23,24,25,26,27,28,29,
1482               30,31,32,33,34,35,36,37,38,39,
1483               40,41,42,43,44,45,46,47,48,a)
1484    )
1485   );
1486   INSERT INTO t1(a) VALUES(1),(2);
1487   SELECT * FROM t1;
1488 } {1 2}
1490 # 2020-03-11 COALESCE() should short-circuit
1491 # See also ticket 3c9eadd2a6ba0aa5
1492 # Both issues stem from the fact that functions that could
1493 # throw exceptions were being factored out into initialization
1494 # code.  The fix was to put those function calls inside of
1495 # OP_Once instead.
1497 reset_db
1498 do_execsql_test func-35.100 {
1499   CREATE TABLE t1(x);
1500   SELECT coalesce(x, abs(-9223372036854775808)) FROM t1;
1501 } {}
1502 do_execsql_test func-35.110 {
1503   SELECT coalesce(x, 'xyz' LIKE printf('%.1000000c','y')) FROM t1;
1504 } {}
1505 do_execsql_test func-35.200 {
1506   CREATE TABLE t0(c0 CHECK(ABS(-9223372036854775808)));
1507   PRAGMA integrity_check;
1508 } {ok}
1510 finish_test