rework hmac key derivation based on low iteration PBKDF2 with static salt mask
[sqlcipher.git] / test / func.test
blobeef05439861b81e924aaaedf5e048284d7bcac17
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
18 # Create a table to work with.
20 do_test func-0.0 {
21   execsql {CREATE TABLE tbl1(t1 text)}
22   foreach word {this program is free software} {
23     execsql "INSERT INTO tbl1 VALUES('$word')"
24   }
25   execsql {SELECT t1 FROM tbl1 ORDER BY t1}
26 } {free is program software this}
27 do_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}
39 # Check out the length() function
41 do_test func-1.0 {
42   execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
43 } {4 2 7 8 4}
44 do_test func-1.1 {
45   set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
46   lappend r $msg
47 } {1 {wrong number of arguments to function length()}}
48 do_test func-1.2 {
49   set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
50   lappend r $msg
51 } {1 {wrong number of arguments to function length()}}
52 do_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}
56 do_test func-1.4 {
57   execsql {SELECT coalesce(length(a),-1) FROM t2}
58 } {1 -1 3 -1 5}
60 # Check out the substr() function
62 do_test func-2.0 {
63   execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
64 } {fr is pr so th}
65 do_test func-2.1 {
66   execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1}
67 } {r s r o h}
68 do_test func-2.2 {
69   execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1}
70 } {ee {} ogr ftw is}
71 do_test func-2.3 {
72   execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
73 } {e s m e s}
74 do_test func-2.4 {
75   execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1}
76 } {e s m e s}
77 do_test func-2.5 {
78   execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1}
79 } {e i a r i}
80 do_test func-2.6 {
81   execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1}
82 } {ee is am re is}
83 do_test func-2.7 {
84   execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1}
85 } {fr {} gr wa th}
86 do_test func-2.8 {
87   execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)}
88 } {this software free program is}
89 do_test func-2.9 {
90   execsql {SELECT substr(a,1,1) FROM t2}
91 } {1 {} 3 {} 6}
92 do_test func-2.10 {
93   execsql {SELECT substr(a,2,2) FROM t2}
94 } {{} {} 45 {} 78}
96 # Only do the following tests if TCL has UTF-8 capabilities
98 if {"\u1234"!="u1234"} {
100 # Put some UTF-8 characters in the database
102 do_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}
108 } "UTF-8 characters contains hi\u1234ho"
109 do_test func-3.1 {
110   execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
111 } {5 10 8 5}
112 do_test func-3.2 {
113   execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
114 } {UT ch co hi}
115 do_test func-3.3 {
116   execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1}
117 } "UTF cha con hi\u1234"
118 do_test func-3.4 {
119   execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1}
120 } "TF ha on i\u1234"
121 do_test func-3.5 {
122   execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1}
123 } "TF- har ont i\u1234h"
124 do_test func-3.6 {
125   execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1}
126 } "F- ar nt \u1234h"
127 do_test func-3.7 {
128   execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1}
129 } "-8 ra ta ho"
130 do_test func-3.8 {
131   execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
132 } "8 s s o"
133 do_test func-3.9 {
134   execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1}
135 } "F- er in \u1234h"
136 do_test func-3.10 {
137   execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1}
138 } "TF- ter ain i\u1234h"
139 do_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}
147 } ;# End \u1234!=u1234
149 # Test the abs() and round() functions.
151 ifcapable !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()}}
162 ifcapable 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()}}
173 do_test func-4.2 {
174   catchsql {SELECT abs() FROM t1}
175 } {1 {wrong number of arguments to function abs()}}
176 ifcapable 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}}
184 ifcapable !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}}
194 do_test func-4.4.1 {
195   execsql {SELECT abs(a) FROM t2}
196 } {1 {} 345 {} 67890}
197 do_test func-4.4.2 {
198   execsql {SELECT abs(t1) FROM tbl1}
199 } {0.0 0.0 0.0 0.0 0.0}
201 ifcapable 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}}
238   # 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.5 + $i]
244     set x2 [expr 40223.0 + $i]
245     do_test func-4.17.$i {
246       execsql {SELECT round($x1);}
247     } $x2
248   }
249   for {set i 1} {$i<999} {incr i} {
250     set x1 [expr 40222.05 + $i]
251     set x2 [expr 40222.10 + $i]
252     do_test func-4.18.$i {
253       execsql {SELECT round($x1,1);}
254     } $x2
255   }
256   do_test func-4.20 {
257     execsql {SELECT round(40223.4999999999);}
258   } {40223.0}
259   do_test func-4.21 {
260     execsql {SELECT round(40224.4999999999);}
261   } {40224.0}
262   do_test func-4.22 {
263     execsql {SELECT round(40225.4999999999);}
264   } {40225.0}
265   for {set i 1} {$i<10} {incr i} {
266     do_test func-4.23.$i {
267       execsql {SELECT round(40223.4999999999,$i);}
268     } {40223.5}
269     do_test func-4.24.$i {
270       execsql {SELECT round(40224.4999999999,$i);}
271     } {40224.5}
272     do_test func-4.25.$i {
273       execsql {SELECT round(40225.4999999999,$i);}
274     } {40225.5}
275   }
276   for {set i 10} {$i<32} {incr i} {
277     do_test func-4.26.$i {
278       execsql {SELECT round(40223.4999999999,$i);}
279     } {40223.4999999999}
280     do_test func-4.27.$i {
281       execsql {SELECT round(40224.4999999999,$i);}
282     } {40224.4999999999}
283     do_test func-4.28.$i {
284       execsql {SELECT round(40225.4999999999,$i);}
285     } {40225.4999999999}
286   }
287   do_test func-4.29 {
288     execsql {SELECT round(1234567890.5);}
289   } {1234567891.0}
290   do_test func-4.30 {
291     execsql {SELECT round(12345678901.5);}
292   } {12345678902.0}
293   do_test func-4.31 {
294     execsql {SELECT round(123456789012.5);}
295   } {123456789013.0}
296   do_test func-4.32 {
297     execsql {SELECT round(1234567890123.5);}
298   } {1234567890124.0}
299   do_test func-4.33 {
300     execsql {SELECT round(12345678901234.5);}
301   } {12345678901235.0}
302   do_test func-4.34 {
303     execsql {SELECT round(1234567890123.35,1);}
304   } {1234567890123.4}
305   do_test func-4.35 {
306     execsql {SELECT round(1234567890123.445,2);}
307   } {1234567890123.45}
308   do_test func-4.36 {
309     execsql {SELECT round(99999999999994.5);}
310   } {99999999999995.0}
311   do_test func-4.37 {
312     execsql {SELECT round(9999999999999.55,1);}
313   } {9999999999999.6}
314   do_test func-4.38 {
315     execsql {SELECT round(9999999999999.555,2);}
316   } {9999999999999.56}
319 # Test the upper() and lower() functions
321 do_test func-5.1 {
322   execsql {SELECT upper(t1) FROM tbl1}
323 } {THIS PROGRAM IS FREE SOFTWARE}
324 do_test func-5.2 {
325   execsql {SELECT lower(upper(t1)) FROM tbl1}
326 } {this program is free software}
327 do_test func-5.3 {
328   execsql {SELECT upper(a), lower(a) FROM t2}
329 } {1 1 {} {} 345 345 {} {} 67890 67890}
330 ifcapable !icu {
331   do_test func-5.4 {
332     catchsql {SELECT upper(a,5) FROM t2}
333   } {1 {wrong number of arguments to function upper()}}
335 do_test func-5.5 {
336   catchsql {SELECT upper(*) FROM t2}
337 } {1 {wrong number of arguments to function upper()}}
339 # Test the coalesce() and nullif() functions
341 do_test func-6.1 {
342   execsql {SELECT coalesce(a,'xyz') FROM t2}
343 } {1 xyz 345 xyz 67890}
344 do_test func-6.2 {
345   execsql {SELECT coalesce(upper(a),'nil') FROM t2}
346 } {1 nil 345 nil 67890}
347 do_test func-6.3 {
348   execsql {SELECT coalesce(nullif(1,1),'nil')}
349 } {nil}
350 do_test func-6.4 {
351   execsql {SELECT coalesce(nullif(1,2),'nil')}
352 } {1}
353 do_test func-6.5 {
354   execsql {SELECT coalesce(nullif(1,NULL),'nil')}
355 } {1}
358 # Test the last_insert_rowid() function
360 do_test func-7.1 {
361   execsql {SELECT last_insert_rowid()}
362 } [db last_insert_rowid]
364 # Tests for aggregate functions and how they handle NULLs.
366 ifcapable floatingpoint {
367   do_test func-8.1 {
368     ifcapable explain {
369       execsql {EXPLAIN SELECT sum(a) FROM t2;}
370     }
371     execsql {
372       SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
373     }
374   } {68236 3 22745.33 1 67890 5}
376 ifcapable !floatingpoint {
377   do_test func-8.1 {
378     ifcapable explain {
379       execsql {EXPLAIN SELECT sum(a) FROM t2;}
380     }
381     execsql {
382       SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2;
383     }
384   } {68236 3 22745.0 1 67890 5}
386 do_test func-8.2 {
387   execsql {
388     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
389   }
390 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
392 ifcapable tempdb {
393   do_test func-8.3 {
394     execsql {
395       CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
396       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
397     }
398   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
399 } else {
400   do_test func-8.3 {
401     execsql {
402       CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
403       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
404     }
405   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
407 do_test func-8.4 {
408   execsql {
409     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
410   }
411 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
412 ifcapable compound {
413   do_test func-8.5 {
414     execsql {
415       SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
416                           UNION ALL SELECT -9223372036854775807)
417     }
418   } {0}
419   do_test func-8.6 {
420     execsql {
421       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
422                           UNION ALL SELECT -9223372036854775807)
423     }
424   } {integer}
425   do_test func-8.7 {
426     execsql {
427       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
428                           UNION ALL SELECT -9223372036854775807)
429     }
430   } {real}
431 ifcapable floatingpoint {
432   do_test func-8.8 {
433     execsql {
434       SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
435                           UNION ALL SELECT -9223372036850000000)
436     }
437   } {1}
439 ifcapable !floatingpoint {
440   do_test func-8.8 {
441     execsql {
442       SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x
443                           UNION ALL SELECT -9223372036850000000)
444     }
445   } {1}
449 # How do you test the random() function in a meaningful, deterministic way?
451 do_test func-9.1 {
452   execsql {
453     SELECT random() is not null;
454   }
455 } {1}
456 do_test func-9.2 {
457   execsql {
458     SELECT typeof(random());
459   }
460 } {integer}
461 do_test func-9.3 {
462   execsql {
463     SELECT randomblob(32) is not null;
464   }
465 } {1}
466 do_test func-9.4 {
467   execsql {
468     SELECT typeof(randomblob(32));
469   }
470 } {blob}
471 do_test func-9.5 {
472   execsql {
473     SELECT length(randomblob(32)), length(randomblob(-5)),
474            length(randomblob(2000))
475   }
476 } {32 1 2000}
478 # The "hex()" function was added in order to be able to render blobs
479 # generated by randomblob().  So this seems like a good place to test
480 # hex().
482 ifcapable bloblit {
483   do_test func-9.10 {
484     execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
485   } {00112233445566778899AABBCCDDEEFF}
487 set encoding [db one {PRAGMA encoding}]
488 if {$encoding=="UTF-16le"} {
489   do_test func-9.11-utf16le {
490     execsql {SELECT hex(replace('abcdefg','ef','12'))}
491   } {6100620063006400310032006700}
492   do_test func-9.12-utf16le {
493     execsql {SELECT hex(replace('abcdefg','','12'))}
494   } {6100620063006400650066006700}
495   do_test func-9.13-utf16le {
496     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
497   } {610061006100610061006100620063006400650066006700}
498 } elseif {$encoding=="UTF-8"} {
499   do_test func-9.11-utf8 {
500     execsql {SELECT hex(replace('abcdefg','ef','12'))}
501   } {61626364313267}
502   do_test func-9.12-utf8 {
503     execsql {SELECT hex(replace('abcdefg','','12'))}
504   } {61626364656667}
505   do_test func-9.13-utf8 {
506     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
507   } {616161616161626364656667}
509   
510 # Use the "sqlite_register_test_function" TCL command which is part of
511 # the text fixture in order to verify correct operation of some of
512 # the user-defined SQL function APIs that are not used by the built-in
513 # functions.
515 set ::DB [sqlite3_connection_pointer db]
516 sqlite_register_test_function $::DB testfunc
517 do_test func-10.1 {
518   catchsql {
519     SELECT testfunc(NULL,NULL);
520   }
521 } {1 {first argument should be one of: int int64 string double null value}}
522 do_test func-10.2 {
523   execsql {
524     SELECT testfunc(
525      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
526      'int', 1234
527     );
528   }
529 } {1234}
530 do_test func-10.3 {
531   execsql {
532     SELECT testfunc(
533      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
534      'string', NULL
535     );
536   }
537 } {{}}
539 ifcapable floatingpoint {
540   do_test func-10.4 {
541     execsql {
542       SELECT testfunc(
543        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
544        'double', 1.234
545       );
546     }
547   } {1.234}
548   do_test func-10.5 {
549     execsql {
550       SELECT testfunc(
551        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
552        'int', 1234,
553        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
554        'string', NULL,
555        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
556        'double', 1.234,
557        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
558        'int', 1234,
559        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
560        'string', NULL,
561        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
562        'double', 1.234
563       );
564     }
565   } {1.234}
568 # Test the built-in sqlite_version(*) SQL function.
570 do_test func-11.1 {
571   execsql {
572     SELECT sqlite_version(*);
573   }
574 } [sqlite3 -version]
576 # Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
577 # etc. are called. These tests use two special user-defined functions
578 # (implemented in func.c) only available in test builds. 
580 # Function test_destructor() takes one argument and returns a copy of the
581 # text form of that argument. A destructor is associated with the return
582 # value. Function test_destructor_count() returns the number of outstanding
583 # destructor calls for values returned by test_destructor().
585 if {[db eval {PRAGMA encoding}]=="UTF-8"} {
586   do_test func-12.1-utf8 {
587     execsql {
588       SELECT test_destructor('hello world'), test_destructor_count();
589     }
590   } {{hello world} 1}
591 } else {
592     ifcapable {utf16} {
593       do_test func-12.1-utf16 {
594         execsql {
595           SELECT test_destructor16('hello world'), test_destructor_count();
596         }
597       } {{hello world} 1}
598     }
600 do_test func-12.2 {
601   execsql {
602     SELECT test_destructor_count();
603   }
604 } {0}
605 do_test func-12.3 {
606   execsql {
607     SELECT test_destructor('hello')||' world'
608   }
609 } {{hello world}}
610 do_test func-12.4 {
611   execsql {
612     SELECT test_destructor_count();
613   }
614 } {0}
615 do_test func-12.5 {
616   execsql {
617     CREATE TABLE t4(x);
618     INSERT INTO t4 VALUES(test_destructor('hello'));
619     INSERT INTO t4 VALUES(test_destructor('world'));
620     SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
621   }
622 } {hello world}
623 do_test func-12.6 {
624   execsql {
625     SELECT test_destructor_count();
626   }
627 } {0}
628 do_test func-12.7 {
629   execsql {
630     DROP TABLE t4;
631   }
632 } {}
635 # Test that the auxdata API for scalar functions works. This test uses
636 # a special user-defined function only available in test builds,
637 # test_auxdata(). Function test_auxdata() takes any number of arguments.
638 do_test func-13.1 {
639   execsql {
640     SELECT test_auxdata('hello world');
641   }
642 } {0}
644 do_test func-13.2 {
645   execsql {
646     CREATE TABLE t4(a, b);
647     INSERT INTO t4 VALUES('abc', 'def');
648     INSERT INTO t4 VALUES('ghi', 'jkl');
649   }
650 } {}
651 do_test func-13.3 {
652   execsql {
653     SELECT test_auxdata('hello world') FROM t4;
654   }
655 } {0 1}
656 do_test func-13.4 {
657   execsql {
658     SELECT test_auxdata('hello world', 123) FROM t4;
659   }
660 } {{0 0} {1 1}}
661 do_test func-13.5 {
662   execsql {
663     SELECT test_auxdata('hello world', a) FROM t4;
664   }
665 } {{0 0} {1 0}}
666 do_test func-13.6 {
667   execsql {
668     SELECT test_auxdata('hello'||'world', a) FROM t4;
669   }
670 } {{0 0} {1 0}}
672 # Test that auxilary data is preserved between calls for SQL variables.
673 do_test func-13.7 {
674   set DB [sqlite3_connection_pointer db]
675   set sql "SELECT test_auxdata( ? , a ) FROM t4;"
676   set STMT [sqlite3_prepare $DB $sql -1 TAIL]
677   sqlite3_bind_text $STMT 1 hello\000 -1
678   set res [list]
679   while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
680     lappend res [sqlite3_column_text $STMT 0]
681   }
682   lappend res [sqlite3_finalize $STMT]
683 } {{0 0} {1 0} SQLITE_OK}
685 # Make sure that a function with a very long name is rejected
686 do_test func-14.1 {
687   catch {
688     db function [string repeat X 254] {return "hello"}
689   } 
690 } {0}
691 do_test func-14.2 {
692   catch {
693     db function [string repeat X 256] {return "hello"}
694   }
695 } {1}
697 do_test func-15.1 {
698   catchsql {select test_error(NULL)}
699 } {1 {}}
700 do_test func-15.2 {
701   catchsql {select test_error('this is the error message')}
702 } {1 {this is the error message}}
703 do_test func-15.3 {
704   catchsql {select test_error('this is the error message',12)}
705 } {1 {this is the error message}}
706 do_test func-15.4 {
707   db errorcode
708 } {12}
710 # Test the quote function for BLOB and NULL values.
711 do_test func-16.1 {
712   execsql {
713     CREATE TABLE tbl2(a, b);
714   }
715   set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
716   sqlite3_bind_blob $::STMT 1 abc 3
717   sqlite3_step $::STMT
718   sqlite3_finalize $::STMT
719   execsql {
720     SELECT quote(a), quote(b) FROM tbl2;
721   }
722 } {X'616263' NULL}
724 # Correctly handle function error messages that include %.  Ticket #1354
726 do_test func-17.1 {
727   proc testfunc1 args {error "Error %d with %s percents %p"}
728   db function testfunc1 ::testfunc1
729   catchsql {
730     SELECT testfunc1(1,2,3);
731   }
732 } {1 {Error %d with %s percents %p}}
734 # The SUM function should return integer results when all inputs are integer.
736 do_test func-18.1 {
737   execsql {
738     CREATE TABLE t5(x);
739     INSERT INTO t5 VALUES(1);
740     INSERT INTO t5 VALUES(-99);
741     INSERT INTO t5 VALUES(10000);
742     SELECT sum(x) FROM t5;
743   }
744 } {9902}
745 ifcapable floatingpoint {
746   do_test func-18.2 {
747     execsql {
748       INSERT INTO t5 VALUES(0.0);
749       SELECT sum(x) FROM t5;
750     }
751   } {9902.0}
754 # The sum of nothing is NULL.  But the sum of all NULLs is NULL.
756 # The TOTAL of nothing is 0.0.
758 do_test func-18.3 {
759   execsql {
760     DELETE FROM t5;
761     SELECT sum(x), total(x) FROM t5;
762   }
763 } {{} 0.0}
764 do_test func-18.4 {
765   execsql {
766     INSERT INTO t5 VALUES(NULL);
767     SELECT sum(x), total(x) FROM t5
768   }
769 } {{} 0.0}
770 do_test func-18.5 {
771   execsql {
772     INSERT INTO t5 VALUES(NULL);
773     SELECT sum(x), total(x) FROM t5
774   }
775 } {{} 0.0}
776 do_test func-18.6 {
777   execsql {
778     INSERT INTO t5 VALUES(123);
779     SELECT sum(x), total(x) FROM t5
780   }
781 } {123 123.0}
783 # Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
784 # an error. The non-standard TOTAL() function continues to give a helpful
785 # result.
787 do_test func-18.10 {
788   execsql {
789     CREATE TABLE t6(x INTEGER);
790     INSERT INTO t6 VALUES(1);
791     INSERT INTO t6 VALUES(1<<62);
792     SELECT sum(x) - ((1<<62)+1) from t6;
793   }
794 } 0
795 do_test func-18.11 {
796   execsql {
797     SELECT typeof(sum(x)) FROM t6
798   }
799 } integer
800 ifcapable floatingpoint {
801   do_test func-18.12 {
802     catchsql {
803       INSERT INTO t6 VALUES(1<<62);
804       SELECT sum(x) - ((1<<62)*2.0+1) from t6;
805     }
806   } {1 {integer overflow}}
807   do_test func-18.13 {
808     execsql {
809       SELECT total(x) - ((1<<62)*2.0+1) FROM t6
810     }
811   } 0.0
813 ifcapable !floatingpoint {
814   do_test func-18.12 {
815     catchsql {
816       INSERT INTO t6 VALUES(1<<62);
817       SELECT sum(x) - ((1<<62)*2+1) from t6;
818     }
819   } {1 {integer overflow}}
820   do_test func-18.13 {
821     execsql {
822       SELECT total(x) - ((1<<62)*2+1) FROM t6
823     }
824   } 0.0
826 if {[working_64bit_int]} {
827   do_test func-18.14 {
828     execsql {
829       SELECT sum(-9223372036854775805);
830     }
831   } -9223372036854775805
833 ifcapable compound&&subquery {
835 do_test func-18.15 {
836   catchsql {
837     SELECT sum(x) FROM 
838        (SELECT 9223372036854775807 AS x UNION ALL
839         SELECT 10 AS x);
840   }
841 } {1 {integer overflow}}
842 if {[working_64bit_int]} {
843   do_test func-18.16 {
844     catchsql {
845       SELECT sum(x) FROM 
846          (SELECT 9223372036854775807 AS x UNION ALL
847           SELECT -10 AS x);
848     }
849   } {0 9223372036854775797}
850   do_test func-18.17 {
851     catchsql {
852       SELECT sum(x) FROM 
853          (SELECT -9223372036854775807 AS x UNION ALL
854           SELECT 10 AS x);
855     }
856   } {0 -9223372036854775797}
858 do_test func-18.18 {
859   catchsql {
860     SELECT sum(x) FROM 
861        (SELECT -9223372036854775807 AS x UNION ALL
862         SELECT -10 AS x);
863   }
864 } {1 {integer overflow}}
865 do_test func-18.19 {
866   catchsql {
867     SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
868   }
869 } {0 -1}
870 do_test func-18.20 {
871   catchsql {
872     SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
873   }
874 } {0 1}
875 do_test func-18.21 {
876   catchsql {
877     SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
878   }
879 } {0 -1}
880 do_test func-18.22 {
881   catchsql {
882     SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
883   }
884 } {0 1}
886 } ;# ifcapable compound&&subquery
888 # Integer overflow on abs()
890 if {[working_64bit_int]} {
891   do_test func-18.31 {
892     catchsql {
893       SELECT abs(-9223372036854775807);
894     }
895   } {0 9223372036854775807}
897 do_test func-18.32 {
898   catchsql {
899     SELECT abs(-9223372036854775807-1);
900   }
901 } {1 {integer overflow}}
903 # The MATCH function exists but is only a stub and always throws an error.
905 do_test func-19.1 {
906   execsql {
907     SELECT match(a,b) FROM t1 WHERE 0;
908   }
909 } {}
910 do_test func-19.2 {
911   catchsql {
912     SELECT 'abc' MATCH 'xyz';
913   }
914 } {1 {unable to use function MATCH in the requested context}}
915 do_test func-19.3 {
916   catchsql {
917     SELECT 'abc' NOT MATCH 'xyz';
918   }
919 } {1 {unable to use function MATCH in the requested context}}
920 do_test func-19.4 {
921   catchsql {
922     SELECT match(1,2,3);
923   }
924 } {1 {wrong number of arguments to function match()}}
926 # Soundex tests.
928 if {![catch {db eval {SELECT soundex('hello')}}]} {
929   set i 0
930   foreach {name sdx} {
931     euler        E460
932     EULER        E460
933     Euler        E460
934     ellery       E460
935     gauss        G200
936     ghosh        G200
937     hilbert      H416
938     Heilbronn    H416
939     knuth        K530
940     kant         K530
941     Lloyd        L300
942     LADD         L300
943     Lukasiewicz  L222
944     Lissajous    L222
945     A            A000
946     12345        ?000
947   } {
948     incr i
949     do_test func-20.$i {
950       execsql {SELECT soundex($name)}
951     } $sdx
952   }
955 # Tests of the REPLACE function.
957 do_test func-21.1 {
958   catchsql {
959     SELECT replace(1,2);
960   }
961 } {1 {wrong number of arguments to function replace()}}
962 do_test func-21.2 {
963   catchsql {
964     SELECT replace(1,2,3,4);
965   }
966 } {1 {wrong number of arguments to function replace()}}
967 do_test func-21.3 {
968   execsql {
969     SELECT typeof(replace("This is the main test string", NULL, "ALT"));
970   }
971 } {null}
972 do_test func-21.4 {
973   execsql {
974     SELECT typeof(replace(NULL, "main", "ALT"));
975   }
976 } {null}
977 do_test func-21.5 {
978   execsql {
979     SELECT typeof(replace("This is the main test string", "main", NULL));
980   }
981 } {null}
982 do_test func-21.6 {
983   execsql {
984     SELECT replace("This is the main test string", "main", "ALT");
985   }
986 } {{This is the ALT test string}}
987 do_test func-21.7 {
988   execsql {
989     SELECT replace("This is the main test string", "main", "larger-main");
990   }
991 } {{This is the larger-main test string}}
992 do_test func-21.8 {
993   execsql {
994     SELECT replace("aaaaaaa", "a", "0123456789");
995   }
996 } {0123456789012345678901234567890123456789012345678901234567890123456789}
998 ifcapable tclvar {
999   do_test func-21.9 {
1000     # Attempt to exploit a buffer-overflow that at one time existed 
1001     # in the REPLACE function. 
1002     set ::str "[string repeat A 29998]CC[string repeat A 35537]"
1003     set ::rep [string repeat B 65536]
1004     execsql {
1005       SELECT LENGTH(REPLACE($::str, 'C', $::rep));
1006     }
1007   } [expr 29998 + 2*65536 + 35537]
1010 # Tests for the TRIM, LTRIM and RTRIM functions.
1012 do_test func-22.1 {
1013   catchsql {SELECT trim(1,2,3)}
1014 } {1 {wrong number of arguments to function trim()}}
1015 do_test func-22.2 {
1016   catchsql {SELECT ltrim(1,2,3)}
1017 } {1 {wrong number of arguments to function ltrim()}}
1018 do_test func-22.3 {
1019   catchsql {SELECT rtrim(1,2,3)}
1020 } {1 {wrong number of arguments to function rtrim()}}
1021 do_test func-22.4 {
1022   execsql {SELECT trim('  hi  ');}
1023 } {hi}
1024 do_test func-22.5 {
1025   execsql {SELECT ltrim('  hi  ');}
1026 } {{hi  }}
1027 do_test func-22.6 {
1028   execsql {SELECT rtrim('  hi  ');}
1029 } {{  hi}}
1030 do_test func-22.7 {
1031   execsql {SELECT trim('  hi  ','xyz');}
1032 } {{  hi  }}
1033 do_test func-22.8 {
1034   execsql {SELECT ltrim('  hi  ','xyz');}
1035 } {{  hi  }}
1036 do_test func-22.9 {
1037   execsql {SELECT rtrim('  hi  ','xyz');}
1038 } {{  hi  }}
1039 do_test func-22.10 {
1040   execsql {SELECT trim('xyxzy  hi  zzzy','xyz');}
1041 } {{  hi  }}
1042 do_test func-22.11 {
1043   execsql {SELECT ltrim('xyxzy  hi  zzzy','xyz');}
1044 } {{  hi  zzzy}}
1045 do_test func-22.12 {
1046   execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
1047 } {{xyxzy  hi  }}
1048 do_test func-22.13 {
1049   execsql {SELECT trim('  hi  ','');}
1050 } {{  hi  }}
1051 if {[db one {PRAGMA encoding}]=="UTF-8"} {
1052   do_test func-22.14 {
1053     execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
1054   } {F48FBFBF6869}
1055   do_test func-22.15 {
1056     execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
1057                              x'6162e1bfbfc280f48fbfbf'))}
1058   } {6869}
1059   do_test func-22.16 {
1060     execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
1061   } {CEB2CEB3}
1063 do_test func-22.20 {
1064   execsql {SELECT typeof(trim(NULL));}
1065 } {null}
1066 do_test func-22.21 {
1067   execsql {SELECT typeof(trim(NULL,'xyz'));}
1068 } {null}
1069 do_test func-22.22 {
1070   execsql {SELECT typeof(trim('hello',NULL));}
1071 } {null}
1073 # This is to test the deprecated sqlite3_aggregate_count() API.
1075 ifcapable deprecated {
1076   do_test func-23.1 {
1077     sqlite3_create_aggregate db
1078     execsql {
1079       SELECT legacy_count() FROM t6;
1080     }
1081   } {3}
1084 # The group_concat() function.
1086 do_test func-24.1 {
1087   execsql {
1088     SELECT group_concat(t1) FROM tbl1
1089   }
1090 } {this,program,is,free,software}
1091 do_test func-24.2 {
1092   execsql {
1093     SELECT group_concat(t1,' ') FROM tbl1
1094   }
1095 } {{this program is free software}}
1096 do_test func-24.3 {
1097   execsql {
1098     SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
1099   }
1100 } {{this 2 program 3 is 4 free 5 software}}
1101 do_test func-24.4 {
1102   execsql {
1103     SELECT group_concat(NULL,t1) FROM tbl1
1104   }
1105 } {{}}
1106 do_test func-24.5 {
1107   execsql {
1108     SELECT group_concat(t1,NULL) FROM tbl1
1109   }
1110 } {thisprogramisfreesoftware}
1111 do_test func-24.6 {
1112   execsql {
1113     SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
1114   }
1115 } {BEGIN-this,program,is,free,software}
1117 # Ticket #3179:  Make sure aggregate functions can take many arguments.
1118 # None of the built-in aggregates do this, so use the md5sum() from the
1119 # test extensions.
1121 unset -nocomplain midargs
1122 set midargs {}
1123 unset -nocomplain midres
1124 set midres {}
1125 unset -nocomplain result
1126 for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
1127   append midargs ,'/$i'
1128   append midres /$i
1129   set result [md5 \
1130      "this${midres}program${midres}is${midres}free${midres}software${midres}"]
1131   set sql "SELECT md5sum(t1$midargs) FROM tbl1"
1132   do_test func-24.7.$i {
1133      db eval $::sql
1134   } $result
1137 # Ticket #3806.  If the initial string in a group_concat is an empty
1138 # string, the separator that follows should still be present.
1140 do_test func-24.8 {
1141   execsql {
1142     SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
1143   }
1144 } {,program,is,free,software}
1145 do_test func-24.9 {
1146   execsql {
1147     SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
1148   }
1149 } {,,,,software}
1151 # Ticket #3923.  Initial empty strings have a separator.  But initial
1152 # NULLs do not.
1154 do_test func-24.10 {
1155   execsql {
1156     SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1
1157   }
1158 } {program,is,free,software}
1159 do_test func-24.11 {
1160   execsql {
1161    SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1
1162   }
1163 } {software}
1164 do_test func-24.12 {
1165   execsql {
1166     SELECT group_concat(CASE t1 WHEN 'this' THEN ''
1167                           WHEN 'program' THEN null ELSE t1 END) FROM tbl1
1168   }
1169 } {,is,free,software}
1172 # Use the test_isolation function to make sure that type conversions
1173 # on function arguments do not effect subsequent arguments.
1175 do_test func-25.1 {
1176   execsql {SELECT test_isolation(t1,t1) FROM tbl1}
1177 } {this program is free software}
1179 # Try to misuse the sqlite3_create_function() interface.  Verify that
1180 # errors are returned.
1182 do_test func-26.1 {
1183   abuse_create_function db
1184 } {}
1186 # The previous test (func-26.1) registered a function with a very long
1187 # function name that takes many arguments and always returns NULL.  Verify
1188 # that this function works correctly.
1190 do_test func-26.2 {
1191   set a {}
1192   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
1193     lappend a $i
1194   }
1195   db eval "
1196      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 ,]);
1197   "
1198 } {{}}
1199 do_test func-26.3 {
1200   set a {}
1201   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
1202     lappend a $i
1203   }
1204   catchsql "
1205      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 ,]);
1206   "
1207 } {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}}
1208 do_test func-26.4 {
1209   set a {}
1210   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
1211     lappend a $i
1212   }
1213   catchsql "
1214      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 ,]);
1215   "
1216 } {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()}}
1217 do_test func-26.5 {
1218   catchsql "
1219      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);
1220   "
1221 } {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}}
1222 do_test func-26.6 {
1223   catchsql "
1224      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);
1225   "
1226 } {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}}
1228 do_test func-27.1 {
1229   catchsql {SELECT coalesce()}
1230 } {1 {wrong number of arguments to function coalesce()}}
1231 do_test func-27.2 {
1232   catchsql {SELECT coalesce(1)}
1233 } {1 {wrong number of arguments to function coalesce()}}
1234 do_test func-27.3 {
1235   catchsql {SELECT coalesce(1,2)}
1236 } {0 1}
1238 # Ticket 2d401a94287b5
1239 # Unknown function in a DEFAULT expression causes a segfault.
1241 do_test func-28.1 {
1242   db eval {
1243     CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1)));
1244   }
1245   catchsql {
1246     INSERT INTO t28(x) VALUES(1);
1247   }
1248 } {1 {unknown function: nosuchfunc()}}
1250 finish_test