Allow min() and max() to be used as window functions.
[sqlite.git] / test / func.test
blob23a3ae4392fe5721c0c7ae5ccd97b56c7502b46b
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}
320 # Test the upper() and lower() functions
322 do_test func-5.1 {
323   execsql {SELECT upper(t1) FROM tbl1}
324 } {THIS PROGRAM IS FREE SOFTWARE}
325 do_test func-5.2 {
326   execsql {SELECT lower(upper(t1)) FROM tbl1}
327 } {this program is free software}
328 do_test func-5.3 {
329   execsql {SELECT upper(a), lower(a) FROM t2}
330 } {1 1 {} {} 345 345 {} {} 67890 67890}
331 ifcapable !icu {
332   do_test func-5.4 {
333     catchsql {SELECT upper(a,5) FROM t2}
334   } {1 {wrong number of arguments to function upper()}}
336 do_test func-5.5 {
337   catchsql {SELECT upper(*) FROM t2}
338 } {1 {wrong number of arguments to function upper()}}
340 # Test the coalesce() and nullif() functions
342 do_test func-6.1 {
343   execsql {SELECT coalesce(a,'xyz') FROM t2}
344 } {1 xyz 345 xyz 67890}
345 do_test func-6.2 {
346   execsql {SELECT coalesce(upper(a),'nil') FROM t2}
347 } {1 nil 345 nil 67890}
348 do_test func-6.3 {
349   execsql {SELECT coalesce(nullif(1,1),'nil')}
350 } {nil}
351 do_test func-6.4 {
352   execsql {SELECT coalesce(nullif(1,2),'nil')}
353 } {1}
354 do_test func-6.5 {
355   execsql {SELECT coalesce(nullif(1,NULL),'nil')}
356 } {1}
359 # Test the last_insert_rowid() function
361 do_test func-7.1 {
362   execsql {SELECT last_insert_rowid()}
363 } [db last_insert_rowid]
365 # Tests for aggregate functions and how they handle NULLs.
367 ifcapable floatingpoint {
368   do_test func-8.1 {
369     ifcapable explain {
370       execsql {EXPLAIN SELECT sum(a) FROM t2;}
371     }
372     execsql {
373       SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
374     }
375   } {68236 3 22745.33 1 67890 5}
377 ifcapable !floatingpoint {
378   do_test func-8.1 {
379     ifcapable explain {
380       execsql {EXPLAIN SELECT sum(a) FROM t2;}
381     }
382     execsql {
383       SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2;
384     }
385   } {68236 3 22745.0 1 67890 5}
387 do_test func-8.2 {
388   execsql {
389     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
390   }
391 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
393 ifcapable tempdb {
394   do_test func-8.3 {
395     execsql {
396       CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
397       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
398     }
399   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
400 } else {
401   do_test func-8.3 {
402     execsql {
403       CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
404       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
405     }
406   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
408 do_test func-8.4 {
409   execsql {
410     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
411   }
412 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
413 ifcapable compound {
414   do_test func-8.5 {
415     execsql {
416       SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
417                           UNION ALL SELECT -9223372036854775807)
418     }
419   } {0}
420   do_test func-8.6 {
421     execsql {
422       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
423                           UNION ALL SELECT -9223372036854775807)
424     }
425   } {integer}
426   do_test func-8.7 {
427     execsql {
428       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
429                           UNION ALL SELECT -9223372036854775807)
430     }
431   } {real}
432 ifcapable floatingpoint {
433   do_test func-8.8 {
434     execsql {
435       SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
436                           UNION ALL SELECT -9223372036850000000)
437     }
438   } {1}
440 ifcapable !floatingpoint {
441   do_test func-8.8 {
442     execsql {
443       SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x
444                           UNION ALL SELECT -9223372036850000000)
445     }
446   } {1}
450 # How do you test the random() function in a meaningful, deterministic way?
452 do_test func-9.1 {
453   execsql {
454     SELECT random() is not null;
455   }
456 } {1}
457 do_test func-9.2 {
458   execsql {
459     SELECT typeof(random());
460   }
461 } {integer}
462 do_test func-9.3 {
463   execsql {
464     SELECT randomblob(32) is not null;
465   }
466 } {1}
467 do_test func-9.4 {
468   execsql {
469     SELECT typeof(randomblob(32));
470   }
471 } {blob}
472 do_test func-9.5 {
473   execsql {
474     SELECT length(randomblob(32)), length(randomblob(-5)),
475            length(randomblob(2000))
476   }
477 } {32 1 2000}
479 # The "hex()" function was added in order to be able to render blobs
480 # generated by randomblob().  So this seems like a good place to test
481 # hex().
483 ifcapable bloblit {
484   do_test func-9.10 {
485     execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
486   } {00112233445566778899AABBCCDDEEFF}
488 set encoding [db one {PRAGMA encoding}]
489 if {$encoding=="UTF-16le"} {
490   do_test func-9.11-utf16le {
491     execsql {SELECT hex(replace('abcdefg','ef','12'))}
492   } {6100620063006400310032006700}
493   do_test func-9.12-utf16le {
494     execsql {SELECT hex(replace('abcdefg','','12'))}
495   } {6100620063006400650066006700}
496   do_test func-9.13-utf16le {
497     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
498   } {610061006100610061006100620063006400650066006700}
499 } elseif {$encoding=="UTF-8"} {
500   do_test func-9.11-utf8 {
501     execsql {SELECT hex(replace('abcdefg','ef','12'))}
502   } {61626364313267}
503   do_test func-9.12-utf8 {
504     execsql {SELECT hex(replace('abcdefg','','12'))}
505   } {61626364656667}
506   do_test func-9.13-utf8 {
507     execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
508   } {616161616161626364656667}
510 do_execsql_test func-9.14 {
511   WITH RECURSIVE c(x) AS (
512      VALUES(1)
513      UNION ALL
514      SELECT x+1 FROM c WHERE x<1040
515   )
516   SELECT 
517     count(*),
518     sum(length(replace(printf('abc%.*cxyz',x,'m'),'m','nnnn'))-(6+x*4))
519   FROM c;
520 } {1040 0}
521   
522 # Use the "sqlite_register_test_function" TCL command which is part of
523 # the text fixture in order to verify correct operation of some of
524 # the user-defined SQL function APIs that are not used by the built-in
525 # functions.
527 set ::DB [sqlite3_connection_pointer db]
528 sqlite_register_test_function $::DB testfunc
529 do_test func-10.1 {
530   catchsql {
531     SELECT testfunc(NULL,NULL);
532   }
533 } {1 {first argument should be one of: int int64 string double null value}}
534 do_test func-10.2 {
535   execsql {
536     SELECT testfunc(
537      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
538      'int', 1234
539     );
540   }
541 } {1234}
542 do_test func-10.3 {
543   execsql {
544     SELECT testfunc(
545      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
546      'string', NULL
547     );
548   }
549 } {{}}
551 ifcapable floatingpoint {
552   do_test func-10.4 {
553     execsql {
554       SELECT testfunc(
555        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
556        'double', 1.234
557       );
558     }
559   } {1.234}
560   do_test func-10.5 {
561     execsql {
562       SELECT testfunc(
563        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
564        'int', 1234,
565        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
566        'string', NULL,
567        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
568        'double', 1.234,
569        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
570        'int', 1234,
571        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
572        'string', NULL,
573        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
574        'double', 1.234
575       );
576     }
577   } {1.234}
580 # Test the built-in sqlite_version(*) SQL function.
582 do_test func-11.1 {
583   execsql {
584     SELECT sqlite_version(*);
585   }
586 } [sqlite3 -version]
588 # Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
589 # etc. are called. These tests use two special user-defined functions
590 # (implemented in func.c) only available in test builds. 
592 # Function test_destructor() takes one argument and returns a copy of the
593 # text form of that argument. A destructor is associated with the return
594 # value. Function test_destructor_count() returns the number of outstanding
595 # destructor calls for values returned by test_destructor().
597 if {[db eval {PRAGMA encoding}]=="UTF-8"} {
598   do_test func-12.1-utf8 {
599     execsql {
600       SELECT test_destructor('hello world'), test_destructor_count();
601     }
602   } {{hello world} 1}
603 } else {
604     ifcapable {utf16} {
605       do_test func-12.1-utf16 {
606         execsql {
607           SELECT test_destructor16('hello world'), test_destructor_count();
608         }
609       } {{hello world} 1}
610     }
612 do_test func-12.2 {
613   execsql {
614     SELECT test_destructor_count();
615   }
616 } {0}
617 do_test func-12.3 {
618   execsql {
619     SELECT test_destructor('hello')||' world'
620   }
621 } {{hello world}}
622 do_test func-12.4 {
623   execsql {
624     SELECT test_destructor_count();
625   }
626 } {0}
627 do_test func-12.5 {
628   execsql {
629     CREATE TABLE t4(x);
630     INSERT INTO t4 VALUES(test_destructor('hello'));
631     INSERT INTO t4 VALUES(test_destructor('world'));
632     SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
633   }
634 } {hello world}
635 do_test func-12.6 {
636   execsql {
637     SELECT test_destructor_count();
638   }
639 } {0}
640 do_test func-12.7 {
641   execsql {
642     DROP TABLE t4;
643   }
644 } {}
647 # Test that the auxdata API for scalar functions works. This test uses
648 # a special user-defined function only available in test builds,
649 # test_auxdata(). Function test_auxdata() takes any number of arguments.
650 do_test func-13.1 {
651   execsql {
652     SELECT test_auxdata('hello world');
653   }
654 } {0}
656 do_test func-13.2 {
657   execsql {
658     CREATE TABLE t4(a, b);
659     INSERT INTO t4 VALUES('abc', 'def');
660     INSERT INTO t4 VALUES('ghi', 'jkl');
661   }
662 } {}
663 do_test func-13.3 {
664   execsql {
665     SELECT test_auxdata('hello world') FROM t4;
666   }
667 } {0 1}
668 do_test func-13.4 {
669   execsql {
670     SELECT test_auxdata('hello world', 123) FROM t4;
671   }
672 } {{0 0} {1 1}}
673 do_test func-13.5 {
674   execsql {
675     SELECT test_auxdata('hello world', a) FROM t4;
676   }
677 } {{0 0} {1 0}}
678 do_test func-13.6 {
679   execsql {
680     SELECT test_auxdata('hello'||'world', a) FROM t4;
681   }
682 } {{0 0} {1 0}}
684 # Test that auxilary data is preserved between calls for SQL variables.
685 do_test func-13.7 {
686   set DB [sqlite3_connection_pointer db]
687   set sql "SELECT test_auxdata( ? , a ) FROM t4;"
688   set STMT [sqlite3_prepare $DB $sql -1 TAIL]
689   sqlite3_bind_text $STMT 1 hello\000 -1
690   set res [list]
691   while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
692     lappend res [sqlite3_column_text $STMT 0]
693   }
694   lappend res [sqlite3_finalize $STMT]
695 } {{0 0} {1 0} SQLITE_OK}
697 # Test that auxiliary data is discarded when a statement is reset.
698 do_execsql_test 13.8.1 {
699   SELECT test_auxdata('constant') FROM t4;
700 } {0 1}
701 do_execsql_test 13.8.2 {
702   SELECT test_auxdata('constant') FROM t4;
703 } {0 1}
704 db cache flush
705 do_execsql_test 13.8.3 {
706   SELECT test_auxdata('constant') FROM t4;
707 } {0 1}
708 set V "one"
709 do_execsql_test 13.8.4 {
710   SELECT test_auxdata($V), $V FROM t4;
711 } {0 one 1 one}
712 set V "two"
713 do_execsql_test 13.8.5 {
714   SELECT test_auxdata($V), $V FROM t4;
715 } {0 two 1 two}
716 db cache flush
717 set V "three"
718 do_execsql_test 13.8.6 {
719   SELECT test_auxdata($V), $V FROM t4;
720 } {0 three 1 three}
723 # Make sure that a function with a very long name is rejected
724 do_test func-14.1 {
725   catch {
726     db function [string repeat X 254] {return "hello"}
727   } 
728 } {0}
729 do_test func-14.2 {
730   catch {
731     db function [string repeat X 256] {return "hello"}
732   }
733 } {1}
735 do_test func-15.1 {
736   catchsql {select test_error(NULL)}
737 } {1 {}}
738 do_test func-15.2 {
739   catchsql {select test_error('this is the error message')}
740 } {1 {this is the error message}}
741 do_test func-15.3 {
742   catchsql {select test_error('this is the error message',12)}
743 } {1 {this is the error message}}
744 do_test func-15.4 {
745   db errorcode
746 } {12}
748 # Test the quote function for BLOB and NULL values.
749 do_test func-16.1 {
750   execsql {
751     CREATE TABLE tbl2(a, b);
752   }
753   set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
754   sqlite3_bind_blob $::STMT 1 abc 3
755   sqlite3_step $::STMT
756   sqlite3_finalize $::STMT
757   execsql {
758     SELECT quote(a), quote(b) FROM tbl2;
759   }
760 } {X'616263' NULL}
762 # Correctly handle function error messages that include %.  Ticket #1354
764 do_test func-17.1 {
765   proc testfunc1 args {error "Error %d with %s percents %p"}
766   db function testfunc1 ::testfunc1
767   catchsql {
768     SELECT testfunc1(1,2,3);
769   }
770 } {1 {Error %d with %s percents %p}}
772 # The SUM function should return integer results when all inputs are integer.
774 do_test func-18.1 {
775   execsql {
776     CREATE TABLE t5(x);
777     INSERT INTO t5 VALUES(1);
778     INSERT INTO t5 VALUES(-99);
779     INSERT INTO t5 VALUES(10000);
780     SELECT sum(x) FROM t5;
781   }
782 } {9902}
783 ifcapable floatingpoint {
784   do_test func-18.2 {
785     execsql {
786       INSERT INTO t5 VALUES(0.0);
787       SELECT sum(x) FROM t5;
788     }
789   } {9902.0}
792 # The sum of nothing is NULL.  But the sum of all NULLs is NULL.
794 # The TOTAL of nothing is 0.0.
796 do_test func-18.3 {
797   execsql {
798     DELETE FROM t5;
799     SELECT sum(x), total(x) FROM t5;
800   }
801 } {{} 0.0}
802 do_test func-18.4 {
803   execsql {
804     INSERT INTO t5 VALUES(NULL);
805     SELECT sum(x), total(x) FROM t5
806   }
807 } {{} 0.0}
808 do_test func-18.5 {
809   execsql {
810     INSERT INTO t5 VALUES(NULL);
811     SELECT sum(x), total(x) FROM t5
812   }
813 } {{} 0.0}
814 do_test func-18.6 {
815   execsql {
816     INSERT INTO t5 VALUES(123);
817     SELECT sum(x), total(x) FROM t5
818   }
819 } {123 123.0}
821 # Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
822 # an error. The non-standard TOTAL() function continues to give a helpful
823 # result.
825 do_test func-18.10 {
826   execsql {
827     CREATE TABLE t6(x INTEGER);
828     INSERT INTO t6 VALUES(1);
829     INSERT INTO t6 VALUES(1<<62);
830     SELECT sum(x) - ((1<<62)+1) from t6;
831   }
832 } 0
833 do_test func-18.11 {
834   execsql {
835     SELECT typeof(sum(x)) FROM t6
836   }
837 } integer
838 ifcapable floatingpoint {
839   do_test func-18.12 {
840     catchsql {
841       INSERT INTO t6 VALUES(1<<62);
842       SELECT sum(x) - ((1<<62)*2.0+1) from t6;
843     }
844   } {1 {integer overflow}}
845   do_test func-18.13 {
846     execsql {
847       SELECT total(x) - ((1<<62)*2.0+1) FROM t6
848     }
849   } 0.0
851 ifcapable !floatingpoint {
852   do_test func-18.12 {
853     catchsql {
854       INSERT INTO t6 VALUES(1<<62);
855       SELECT sum(x) - ((1<<62)*2+1) from t6;
856     }
857   } {1 {integer overflow}}
858   do_test func-18.13 {
859     execsql {
860       SELECT total(x) - ((1<<62)*2+1) FROM t6
861     }
862   } 0.0
864 if {[working_64bit_int]} {
865   do_test func-18.14 {
866     execsql {
867       SELECT sum(-9223372036854775805);
868     }
869   } -9223372036854775805
871 ifcapable compound&&subquery {
873 do_test func-18.15 {
874   catchsql {
875     SELECT sum(x) FROM 
876        (SELECT 9223372036854775807 AS x UNION ALL
877         SELECT 10 AS x);
878   }
879 } {1 {integer overflow}}
880 if {[working_64bit_int]} {
881   do_test func-18.16 {
882     catchsql {
883       SELECT sum(x) FROM 
884          (SELECT 9223372036854775807 AS x UNION ALL
885           SELECT -10 AS x);
886     }
887   } {0 9223372036854775797}
888   do_test func-18.17 {
889     catchsql {
890       SELECT sum(x) FROM 
891          (SELECT -9223372036854775807 AS x UNION ALL
892           SELECT 10 AS x);
893     }
894   } {0 -9223372036854775797}
896 do_test func-18.18 {
897   catchsql {
898     SELECT sum(x) FROM 
899        (SELECT -9223372036854775807 AS x UNION ALL
900         SELECT -10 AS x);
901   }
902 } {1 {integer overflow}}
903 do_test func-18.19 {
904   catchsql {
905     SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
906   }
907 } {0 -1}
908 do_test func-18.20 {
909   catchsql {
910     SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
911   }
912 } {0 1}
913 do_test func-18.21 {
914   catchsql {
915     SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
916   }
917 } {0 -1}
918 do_test func-18.22 {
919   catchsql {
920     SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
921   }
922 } {0 1}
924 } ;# ifcapable compound&&subquery
926 # Integer overflow on abs()
928 if {[working_64bit_int]} {
929   do_test func-18.31 {
930     catchsql {
931       SELECT abs(-9223372036854775807);
932     }
933   } {0 9223372036854775807}
935 do_test func-18.32 {
936   catchsql {
937     SELECT abs(-9223372036854775807-1);
938   }
939 } {1 {integer overflow}}
941 # The MATCH function exists but is only a stub and always throws an error.
943 do_test func-19.1 {
944   execsql {
945     SELECT match(a,b) FROM t1 WHERE 0;
946   }
947 } {}
948 do_test func-19.2 {
949   catchsql {
950     SELECT 'abc' MATCH 'xyz';
951   }
952 } {1 {unable to use function MATCH in the requested context}}
953 do_test func-19.3 {
954   catchsql {
955     SELECT 'abc' NOT MATCH 'xyz';
956   }
957 } {1 {unable to use function MATCH in the requested context}}
958 do_test func-19.4 {
959   catchsql {
960     SELECT match(1,2,3);
961   }
962 } {1 {wrong number of arguments to function match()}}
964 # Soundex tests.
966 if {![catch {db eval {SELECT soundex('hello')}}]} {
967   set i 0
968   foreach {name sdx} {
969     euler        E460
970     EULER        E460
971     Euler        E460
972     ellery       E460
973     gauss        G200
974     ghosh        G200
975     hilbert      H416
976     Heilbronn    H416
977     knuth        K530
978     kant         K530
979     Lloyd        L300
980     LADD         L300
981     Lukasiewicz  L222
982     Lissajous    L222
983     A            A000
984     12345        ?000
985   } {
986     incr i
987     do_test func-20.$i {
988       execsql {SELECT soundex($name)}
989     } $sdx
990   }
993 # Tests of the REPLACE function.
995 do_test func-21.1 {
996   catchsql {
997     SELECT replace(1,2);
998   }
999 } {1 {wrong number of arguments to function replace()}}
1000 do_test func-21.2 {
1001   catchsql {
1002     SELECT replace(1,2,3,4);
1003   }
1004 } {1 {wrong number of arguments to function replace()}}
1005 do_test func-21.3 {
1006   execsql {
1007     SELECT typeof(replace("This is the main test string", NULL, "ALT"));
1008   }
1009 } {null}
1010 do_test func-21.4 {
1011   execsql {
1012     SELECT typeof(replace(NULL, "main", "ALT"));
1013   }
1014 } {null}
1015 do_test func-21.5 {
1016   execsql {
1017     SELECT typeof(replace("This is the main test string", "main", NULL));
1018   }
1019 } {null}
1020 do_test func-21.6 {
1021   execsql {
1022     SELECT replace("This is the main test string", "main", "ALT");
1023   }
1024 } {{This is the ALT test string}}
1025 do_test func-21.7 {
1026   execsql {
1027     SELECT replace("This is the main test string", "main", "larger-main");
1028   }
1029 } {{This is the larger-main test string}}
1030 do_test func-21.8 {
1031   execsql {
1032     SELECT replace("aaaaaaa", "a", "0123456789");
1033   }
1034 } {0123456789012345678901234567890123456789012345678901234567890123456789}
1036 ifcapable tclvar {
1037   do_test func-21.9 {
1038     # Attempt to exploit a buffer-overflow that at one time existed 
1039     # in the REPLACE function. 
1040     set ::str "[string repeat A 29998]CC[string repeat A 35537]"
1041     set ::rep [string repeat B 65536]
1042     execsql {
1043       SELECT LENGTH(REPLACE($::str, 'C', $::rep));
1044     }
1045   } [expr 29998 + 2*65536 + 35537]
1048 # Tests for the TRIM, LTRIM and RTRIM functions.
1050 do_test func-22.1 {
1051   catchsql {SELECT trim(1,2,3)}
1052 } {1 {wrong number of arguments to function trim()}}
1053 do_test func-22.2 {
1054   catchsql {SELECT ltrim(1,2,3)}
1055 } {1 {wrong number of arguments to function ltrim()}}
1056 do_test func-22.3 {
1057   catchsql {SELECT rtrim(1,2,3)}
1058 } {1 {wrong number of arguments to function rtrim()}}
1059 do_test func-22.4 {
1060   execsql {SELECT trim('  hi  ');}
1061 } {hi}
1062 do_test func-22.5 {
1063   execsql {SELECT ltrim('  hi  ');}
1064 } {{hi  }}
1065 do_test func-22.6 {
1066   execsql {SELECT rtrim('  hi  ');}
1067 } {{  hi}}
1068 do_test func-22.7 {
1069   execsql {SELECT trim('  hi  ','xyz');}
1070 } {{  hi  }}
1071 do_test func-22.8 {
1072   execsql {SELECT ltrim('  hi  ','xyz');}
1073 } {{  hi  }}
1074 do_test func-22.9 {
1075   execsql {SELECT rtrim('  hi  ','xyz');}
1076 } {{  hi  }}
1077 do_test func-22.10 {
1078   execsql {SELECT trim('xyxzy  hi  zzzy','xyz');}
1079 } {{  hi  }}
1080 do_test func-22.11 {
1081   execsql {SELECT ltrim('xyxzy  hi  zzzy','xyz');}
1082 } {{  hi  zzzy}}
1083 do_test func-22.12 {
1084   execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
1085 } {{xyxzy  hi  }}
1086 do_test func-22.13 {
1087   execsql {SELECT trim('  hi  ','');}
1088 } {{  hi  }}
1089 if {[db one {PRAGMA encoding}]=="UTF-8"} {
1090   do_test func-22.14 {
1091     execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
1092   } {F48FBFBF6869}
1093   do_test func-22.15 {
1094     execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
1095                              x'6162e1bfbfc280f48fbfbf'))}
1096   } {6869}
1097   do_test func-22.16 {
1098     execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
1099   } {CEB2CEB3}
1101 do_test func-22.20 {
1102   execsql {SELECT typeof(trim(NULL));}
1103 } {null}
1104 do_test func-22.21 {
1105   execsql {SELECT typeof(trim(NULL,'xyz'));}
1106 } {null}
1107 do_test func-22.22 {
1108   execsql {SELECT typeof(trim('hello',NULL));}
1109 } {null}
1111 # This is to test the deprecated sqlite3_aggregate_count() API.
1113 ifcapable deprecated {
1114   do_test func-23.1 {
1115     sqlite3_create_aggregate db
1116     execsql {
1117       SELECT legacy_count() FROM t6;
1118     }
1119   } {3}
1122 # The group_concat() function.
1124 do_test func-24.1 {
1125   execsql {
1126     SELECT group_concat(t1) FROM tbl1
1127   }
1128 } {this,program,is,free,software}
1129 do_test func-24.2 {
1130   execsql {
1131     SELECT group_concat(t1,' ') FROM tbl1
1132   }
1133 } {{this program is free software}}
1134 do_test func-24.3 {
1135   execsql {
1136     SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
1137   }
1138 } {{this 2 program 3 is 4 free 5 software}}
1139 do_test func-24.4 {
1140   execsql {
1141     SELECT group_concat(NULL,t1) FROM tbl1
1142   }
1143 } {{}}
1144 do_test func-24.5 {
1145   execsql {
1146     SELECT group_concat(t1,NULL) FROM tbl1
1147   }
1148 } {thisprogramisfreesoftware}
1149 do_test func-24.6 {
1150   execsql {
1151     SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
1152   }
1153 } {BEGIN-this,program,is,free,software}
1155 # Ticket #3179:  Make sure aggregate functions can take many arguments.
1156 # None of the built-in aggregates do this, so use the md5sum() from the
1157 # test extensions.
1159 unset -nocomplain midargs
1160 set midargs {}
1161 unset -nocomplain midres
1162 set midres {}
1163 unset -nocomplain result
1164 for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} {
1165   append midargs ,'/$i'
1166   append midres /$i
1167   set result [md5 \
1168      "this${midres}program${midres}is${midres}free${midres}software${midres}"]
1169   set sql "SELECT md5sum(t1$midargs) FROM tbl1"
1170   do_test func-24.7.$i {
1171      db eval $::sql
1172   } $result
1175 # Ticket #3806.  If the initial string in a group_concat is an empty
1176 # string, the separator that follows should still be present.
1178 do_test func-24.8 {
1179   execsql {
1180     SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1
1181   }
1182 } {,program,is,free,software}
1183 do_test func-24.9 {
1184   execsql {
1185     SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1
1186   }
1187 } {,,,,software}
1189 # Ticket #3923.  Initial empty strings have a separator.  But initial
1190 # NULLs do not.
1192 do_test func-24.10 {
1193   execsql {
1194     SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1
1195   }
1196 } {program,is,free,software}
1197 do_test func-24.11 {
1198   execsql {
1199    SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1
1200   }
1201 } {software}
1202 do_test func-24.12 {
1203   execsql {
1204     SELECT group_concat(CASE t1 WHEN 'this' THEN ''
1205                           WHEN 'program' THEN null ELSE t1 END) FROM tbl1
1206   }
1207 } {,is,free,software}
1208 # Tests to verify ticket http://www.sqlite.org/src/tktview/55746f9e65f8587c0
1209 do_test func-24.13 {
1210   execsql {
1211     SELECT typeof(group_concat(x)) FROM (SELECT '' AS x);
1212   }
1213 } {text}
1214 do_test func-24.14 {
1215   execsql {
1216     SELECT typeof(group_concat(x,''))
1217       FROM (SELECT '' AS x UNION ALL SELECT '');
1218   }
1219 } {text}
1222 # Use the test_isolation function to make sure that type conversions
1223 # on function arguments do not effect subsequent arguments.
1225 do_test func-25.1 {
1226   execsql {SELECT test_isolation(t1,t1) FROM tbl1}
1227 } {this program is free software}
1229 # Try to misuse the sqlite3_create_function() interface.  Verify that
1230 # errors are returned.
1232 do_test func-26.1 {
1233   abuse_create_function db
1234 } {}
1236 # The previous test (func-26.1) registered a function with a very long
1237 # function name that takes many arguments and always returns NULL.  Verify
1238 # that this function works correctly.
1240 do_test func-26.2 {
1241   set a {}
1242   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
1243     lappend a $i
1244   }
1245   db eval "
1246      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 ,]);
1247   "
1248 } {{}}
1249 do_test func-26.3 {
1250   set a {}
1251   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
1252     lappend a $i
1253   }
1254   catchsql "
1255      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 ,]);
1256   "
1257 } {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}}
1258 do_test func-26.4 {
1259   set a {}
1260   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
1261     lappend a $i
1262   }
1263   catchsql "
1264      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 ,]);
1265   "
1266 } {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()}}
1267 do_test func-26.5 {
1268   catchsql "
1269      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);
1270   "
1271 } {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}}
1272 do_test func-26.6 {
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_123456789a(0);
1275   "
1276 } {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}}
1278 do_test func-27.1 {
1279   catchsql {SELECT coalesce()}
1280 } {1 {wrong number of arguments to function coalesce()}}
1281 do_test func-27.2 {
1282   catchsql {SELECT coalesce(1)}
1283 } {1 {wrong number of arguments to function coalesce()}}
1284 do_test func-27.3 {
1285   catchsql {SELECT coalesce(1,2)}
1286 } {0 1}
1288 # Ticket 2d401a94287b5
1289 # Unknown function in a DEFAULT expression causes a segfault.
1291 do_test func-28.1 {
1292   db eval {
1293     CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1)));
1294   }
1295   catchsql {
1296     INSERT INTO t28(x) VALUES(1);
1297   }
1298 } {1 {unknown function: nosuchfunc()}}
1300 # Verify that the length() and typeof() functions do not actually load
1301 # the content of their argument.
1303 do_test func-29.1 {
1304   db eval {
1305     CREATE TABLE t29(id INTEGER PRIMARY KEY, x, y);
1306     INSERT INTO t29 VALUES(1, 2, 3), (2, NULL, 4), (3, 4.5, 5);
1307     INSERT INTO t29 VALUES(4, randomblob(1000000), 6);
1308     INSERT INTO t29 VALUES(5, "hello", 7);
1309   }
1310   db close
1311   sqlite3 db test.db
1312   sqlite3_db_status db CACHE_MISS 1
1313   db eval {SELECT typeof(x), length(x), typeof(y) FROM t29 ORDER BY id}
1314 } {integer 1 integer null {} integer real 3 integer blob 1000000 integer text 5 integer}
1315 do_test func-29.2 {
1316   set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
1317   if {$x<5} {set x 1}
1318   set x
1319 } {1}
1320 do_test func-29.3 {
1321   db close
1322   sqlite3 db test.db
1323   sqlite3_db_status db CACHE_MISS 1
1324   db eval {SELECT typeof(+x) FROM t29 ORDER BY id}
1325 } {integer null real blob text}
1326 if {[permutation] != "mmap"} {
1327   ifcapable !direct_read {
1328     do_test func-29.4 {
1329       set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
1330       if {$x>100} {set x many}
1331       set x
1332     } {many}
1333   }
1335 do_test func-29.5 {
1336   db close
1337   sqlite3 db test.db
1338   sqlite3_db_status db CACHE_MISS 1
1339   db eval {SELECT sum(length(x)) FROM t29}
1340 } {1000009}
1341 do_test func-29.6 {
1342   set x [lindex [sqlite3_db_status db CACHE_MISS 1] 1]
1343   if {$x<5} {set x 1}
1344   set x
1345 } {1}
1347 # The OP_Column opcode has an optimization that avoids loading content
1348 # for fields with content-length=0 when the content offset is on an overflow
1349 # page.  Make sure the optimization works.
1351 do_execsql_test func-29.10 {
1352   CREATE TABLE t29b(a,b,c,d,e,f,g,h,i);
1353   INSERT INTO t29b 
1354    VALUES(1, hex(randomblob(2000)), null, 0, 1, '', zeroblob(0),'x',x'01');
1355   SELECT typeof(c), typeof(d), typeof(e), typeof(f),
1356          typeof(g), typeof(h), typeof(i) FROM t29b;
1357 } {null integer integer text blob text blob}
1358 do_execsql_test func-29.11 {
1359   SELECT length(f), length(g), length(h), length(i) FROM t29b;
1360 } {0 0 1 1}
1361 do_execsql_test func-29.12 {
1362   SELECT quote(f), quote(g), quote(h), quote(i) FROM t29b;
1363 } {'' X'' 'x' X'01'}
1365 # EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric
1366 # unicode code point corresponding to the first character of the string
1367 # X.
1369 # EVIDENCE-OF: R-55469-62130 The char(X1,X2,...,XN) function returns a
1370 # string composed of characters having the unicode code point values of
1371 # integers X1 through XN, respectively.
1373 do_execsql_test func-30.1 {SELECT unicode('$');} 36
1374 do_execsql_test func-30.2 [subst {SELECT unicode('\u00A2');}] 162
1375 do_execsql_test func-30.3 [subst {SELECT unicode('\u20AC');}] 8364
1376 do_execsql_test func-30.4 {SELECT char(36,162,8364);} [subst {$\u00A2\u20AC}]
1378 for {set i 1} {$i<0xd800} {incr i 13} {
1379   do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
1381 for {set i 57344} {$i<=0xfffd} {incr i 17} {
1382   if {$i==0xfeff} continue
1383   do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
1385 for {set i 65536} {$i<=0x10ffff} {incr i 139} {
1386   do_execsql_test func-30.5.$i {SELECT unicode(char($i))} $i
1389 # Test char().
1391 do_execsql_test func-31.1 { 
1392   SELECT char(), length(char()), typeof(char()) 
1393 } {{} 0 text}
1394 finish_test