xref: /sqlite-3.40.0/test/func.test (revision dfbc3a8a)
1b19a2bc6Sdrh# 2001 September 15
2ff6e9116Sdrh#
3b19a2bc6Sdrh# The author disclaims copyright to this source code.  In place of
4b19a2bc6Sdrh# a legal notice, here is a blessing:
5ff6e9116Sdrh#
6b19a2bc6Sdrh#    May you do good and not evil.
7b19a2bc6Sdrh#    May you find forgiveness for yourself and forgive others.
8b19a2bc6Sdrh#    May you share freely, never taking more than you give.
9ff6e9116Sdrh#
10ff6e9116Sdrh#***********************************************************************
11ff6e9116Sdrh# This file implements regression tests for SQLite library.  The
12ff6e9116Sdrh# focus of this file is testing built-in functions.
13ff6e9116Sdrh#
14*dfbc3a8aSdrh# $Id: func.test,v 1.88 2009/01/31 22:28:49 drh Exp $
15ff6e9116Sdrh
16ff6e9116Sdrhset testdir [file dirname $argv0]
17ff6e9116Sdrhsource $testdir/tester.tcl
18ff6e9116Sdrh
19ff6e9116Sdrh# Create a table to work with.
20ff6e9116Sdrh#
21297ecf14Sdrhdo_test func-0.0 {
22ff6e9116Sdrh  execsql {CREATE TABLE tbl1(t1 text)}
23ff6e9116Sdrh  foreach word {this program is free software} {
24ff6e9116Sdrh    execsql "INSERT INTO tbl1 VALUES('$word')"
25ff6e9116Sdrh  }
26ff6e9116Sdrh  execsql {SELECT t1 FROM tbl1 ORDER BY t1}
27ff6e9116Sdrh} {free is program software this}
28832508b7Sdrhdo_test func-0.1 {
29832508b7Sdrh  execsql {
30832508b7Sdrh     CREATE TABLE t2(a);
31832508b7Sdrh     INSERT INTO t2 VALUES(1);
32832508b7Sdrh     INSERT INTO t2 VALUES(NULL);
33832508b7Sdrh     INSERT INTO t2 VALUES(345);
34832508b7Sdrh     INSERT INTO t2 VALUES(NULL);
35832508b7Sdrh     INSERT INTO t2 VALUES(67890);
36832508b7Sdrh     SELECT * FROM t2;
37832508b7Sdrh  }
38832508b7Sdrh} {1 {} 345 {} 67890}
39ff6e9116Sdrh
40ff6e9116Sdrh# Check out the length() function
41ff6e9116Sdrh#
42ff6e9116Sdrhdo_test func-1.0 {
43ff6e9116Sdrh  execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
44ff6e9116Sdrh} {4 2 7 8 4}
45ff6e9116Sdrhdo_test func-1.1 {
46ff6e9116Sdrh  set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
47ff6e9116Sdrh  lappend r $msg
4889425d5eSdrh} {1 {wrong number of arguments to function length()}}
49ff6e9116Sdrhdo_test func-1.2 {
50ff6e9116Sdrh  set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
51ff6e9116Sdrh  lappend r $msg
5289425d5eSdrh} {1 {wrong number of arguments to function length()}}
53ff6e9116Sdrhdo_test func-1.3 {
54ff6e9116Sdrh  execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1)
55ff6e9116Sdrh           ORDER BY length(t1)}
56ff6e9116Sdrh} {2 1 4 2 7 1 8 1}
57832508b7Sdrhdo_test func-1.4 {
58bb113518Sdrh  execsql {SELECT coalesce(length(a),-1) FROM t2}
59bb113518Sdrh} {1 -1 3 -1 5}
60ff6e9116Sdrh
61ff6e9116Sdrh# Check out the substr() function
62ff6e9116Sdrh#
63ff6e9116Sdrhdo_test func-2.0 {
64ff6e9116Sdrh  execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
65ff6e9116Sdrh} {fr is pr so th}
66ff6e9116Sdrhdo_test func-2.1 {
67ff6e9116Sdrh  execsql {SELECT substr(t1,2,1) FROM tbl1 ORDER BY t1}
68ff6e9116Sdrh} {r s r o h}
69ff6e9116Sdrhdo_test func-2.2 {
70ff6e9116Sdrh  execsql {SELECT substr(t1,3,3) FROM tbl1 ORDER BY t1}
71ff6e9116Sdrh} {ee {} ogr ftw is}
72ff6e9116Sdrhdo_test func-2.3 {
73ff6e9116Sdrh  execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
74ff6e9116Sdrh} {e s m e s}
75ff6e9116Sdrhdo_test func-2.4 {
76ff6e9116Sdrh  execsql {SELECT substr(t1,-1,2) FROM tbl1 ORDER BY t1}
77ff6e9116Sdrh} {e s m e s}
78ff6e9116Sdrhdo_test func-2.5 {
79ff6e9116Sdrh  execsql {SELECT substr(t1,-2,1) FROM tbl1 ORDER BY t1}
80ff6e9116Sdrh} {e i a r i}
81ff6e9116Sdrhdo_test func-2.6 {
82ff6e9116Sdrh  execsql {SELECT substr(t1,-2,2) FROM tbl1 ORDER BY t1}
83ff6e9116Sdrh} {ee is am re is}
84ff6e9116Sdrhdo_test func-2.7 {
85ff6e9116Sdrh  execsql {SELECT substr(t1,-4,2) FROM tbl1 ORDER BY t1}
86ff6e9116Sdrh} {fr {} gr wa th}
87ff6e9116Sdrhdo_test func-2.8 {
88ff6e9116Sdrh  execsql {SELECT t1 FROM tbl1 ORDER BY substr(t1,2,20)}
89ff6e9116Sdrh} {this software free program is}
90832508b7Sdrhdo_test func-2.9 {
91832508b7Sdrh  execsql {SELECT substr(a,1,1) FROM t2}
92832508b7Sdrh} {1 {} 3 {} 6}
93832508b7Sdrhdo_test func-2.10 {
94832508b7Sdrh  execsql {SELECT substr(a,2,2) FROM t2}
95832508b7Sdrh} {{} {} 45 {} 78}
96ff6e9116Sdrh
97df014893Sdrh# Only do the following tests if TCL has UTF-8 capabilities
98297ecf14Sdrh#
99df014893Sdrhif {"\u1234"!="u1234"} {
100297ecf14Sdrh
101297ecf14Sdrh# Put some UTF-8 characters in the database
102297ecf14Sdrh#
103297ecf14Sdrhdo_test func-3.0 {
104297ecf14Sdrh  execsql {DELETE FROM tbl1}
105297ecf14Sdrh  foreach word "contains UTF-8 characters hi\u1234ho" {
106297ecf14Sdrh    execsql "INSERT INTO tbl1 VALUES('$word')"
107297ecf14Sdrh  }
108297ecf14Sdrh  execsql {SELECT t1 FROM tbl1 ORDER BY t1}
109a9e99aeeSdrh} "UTF-8 characters contains hi\u1234ho"
110297ecf14Sdrhdo_test func-3.1 {
111297ecf14Sdrh  execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
112a9e99aeeSdrh} {5 10 8 5}
113297ecf14Sdrhdo_test func-3.2 {
114297ecf14Sdrh  execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1}
115a9e99aeeSdrh} {UT ch co hi}
116297ecf14Sdrhdo_test func-3.3 {
117297ecf14Sdrh  execsql {SELECT substr(t1,1,3) FROM tbl1 ORDER BY t1}
118a9e99aeeSdrh} "UTF cha con hi\u1234"
119297ecf14Sdrhdo_test func-3.4 {
120297ecf14Sdrh  execsql {SELECT substr(t1,2,2) FROM tbl1 ORDER BY t1}
121a9e99aeeSdrh} "TF ha on i\u1234"
122297ecf14Sdrhdo_test func-3.5 {
123297ecf14Sdrh  execsql {SELECT substr(t1,2,3) FROM tbl1 ORDER BY t1}
124a9e99aeeSdrh} "TF- har ont i\u1234h"
125297ecf14Sdrhdo_test func-3.6 {
126297ecf14Sdrh  execsql {SELECT substr(t1,3,2) FROM tbl1 ORDER BY t1}
127a9e99aeeSdrh} "F- ar nt \u1234h"
128297ecf14Sdrhdo_test func-3.7 {
129297ecf14Sdrh  execsql {SELECT substr(t1,4,2) FROM tbl1 ORDER BY t1}
130a9e99aeeSdrh} "-8 ra ta ho"
131297ecf14Sdrhdo_test func-3.8 {
132297ecf14Sdrh  execsql {SELECT substr(t1,-1,1) FROM tbl1 ORDER BY t1}
133a9e99aeeSdrh} "8 s s o"
134297ecf14Sdrhdo_test func-3.9 {
135297ecf14Sdrh  execsql {SELECT substr(t1,-3,2) FROM tbl1 ORDER BY t1}
136a9e99aeeSdrh} "F- er in \u1234h"
137297ecf14Sdrhdo_test func-3.10 {
138297ecf14Sdrh  execsql {SELECT substr(t1,-4,3) FROM tbl1 ORDER BY t1}
139a9e99aeeSdrh} "TF- ter ain i\u1234h"
140832508b7Sdrhdo_test func-3.99 {
141832508b7Sdrh  execsql {DELETE FROM tbl1}
142832508b7Sdrh  foreach word {this program is free software} {
143832508b7Sdrh    execsql "INSERT INTO tbl1 VALUES('$word')"
144832508b7Sdrh  }
145832508b7Sdrh  execsql {SELECT t1 FROM tbl1}
146832508b7Sdrh} {this program is free software}
147297ecf14Sdrh
148df014893Sdrh} ;# End \u1234!=u1234
149297ecf14Sdrh
150bf4133cbSdrh# Test the abs() and round() functions.
151bf4133cbSdrh#
152bf4133cbSdrhdo_test func-4.1 {
153bf4133cbSdrh  execsql {
154bf4133cbSdrh    CREATE TABLE t1(a,b,c);
155bf4133cbSdrh    INSERT INTO t1 VALUES(1,2,3);
156bf4133cbSdrh    INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
157bf4133cbSdrh    INSERT INTO t1 VALUES(3,-2,-5);
158bf4133cbSdrh  }
159bf4133cbSdrh  catchsql {SELECT abs(a,b) FROM t1}
16089425d5eSdrh} {1 {wrong number of arguments to function abs()}}
161bf4133cbSdrhdo_test func-4.2 {
162bf4133cbSdrh  catchsql {SELECT abs() FROM t1}
16389425d5eSdrh} {1 {wrong number of arguments to function abs()}}
164bf4133cbSdrhdo_test func-4.3 {
165bf4133cbSdrh  catchsql {SELECT abs(b) FROM t1 ORDER BY a}
166bf4133cbSdrh} {0 {2 1.2345678901234 2}}
167bf4133cbSdrhdo_test func-4.4 {
168bf4133cbSdrh  catchsql {SELECT abs(c) FROM t1 ORDER BY a}
1693d1bfeaaSdanielk1977} {0 {3 12345.6789 5}}
170832508b7Sdrhdo_test func-4.4.1 {
171832508b7Sdrh  execsql {SELECT abs(a) FROM t2}
172832508b7Sdrh} {1 {} 345 {} 67890}
173832508b7Sdrhdo_test func-4.4.2 {
174832508b7Sdrh  execsql {SELECT abs(t1) FROM tbl1}
17592febd92Sdrh} {0.0 0.0 0.0 0.0 0.0}
176bf4133cbSdrh
177bf4133cbSdrhdo_test func-4.5 {
178bf4133cbSdrh  catchsql {SELECT round(a,b,c) FROM t1}
17989425d5eSdrh} {1 {wrong number of arguments to function round()}}
180bf4133cbSdrhdo_test func-4.6 {
1818aff1015Sdrh  catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
182d589a92aSdrh} {0 {-2.0 1.23 2.0}}
183bf4133cbSdrhdo_test func-4.7 {
184bf4133cbSdrh  catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
185d589a92aSdrh} {0 {2.0 1.0 -2.0}}
186bf4133cbSdrhdo_test func-4.8 {
187bf4133cbSdrh  catchsql {SELECT round(c) FROM t1 ORDER BY a}
188d589a92aSdrh} {0 {3.0 -12346.0 -5.0}}
189bf4133cbSdrhdo_test func-4.9 {
190bf4133cbSdrh  catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
191d589a92aSdrh} {0 {3.0 -12345.68 -5.0}}
192bf4133cbSdrhdo_test func-4.10 {
19301a34661Sdrh  catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a}
194d589a92aSdrh} {0 {x3.0y x-12345.68y x-5.0y}}
19501a34661Sdrhdo_test func-4.11 {
196bf4133cbSdrh  catchsql {SELECT round() FROM t1 ORDER BY a}
19789425d5eSdrh} {1 {wrong number of arguments to function round()}}
198832508b7Sdrhdo_test func-4.12 {
199bb113518Sdrh  execsql {SELECT coalesce(round(a,2),'nil') FROM t2}
200d589a92aSdrh} {1.0 nil 345.0 nil 67890.0}
201832508b7Sdrhdo_test func-4.13 {
202832508b7Sdrh  execsql {SELECT round(t1,2) FROM tbl1}
203d589a92aSdrh} {0.0 0.0 0.0 0.0 0.0}
204d589a92aSdrhdo_test func-4.14 {
205d589a92aSdrh  execsql {SELECT typeof(round(5.1,1));}
206d589a92aSdrh} {real}
207d589a92aSdrhdo_test func-4.15 {
208d589a92aSdrh  execsql {SELECT typeof(round(5.1));}
209d589a92aSdrh} {real}
210d589a92aSdrh
211832508b7Sdrh
212832508b7Sdrh# Test the upper() and lower() functions
213832508b7Sdrh#
214832508b7Sdrhdo_test func-5.1 {
215832508b7Sdrh  execsql {SELECT upper(t1) FROM tbl1}
216832508b7Sdrh} {THIS PROGRAM IS FREE SOFTWARE}
217832508b7Sdrhdo_test func-5.2 {
218832508b7Sdrh  execsql {SELECT lower(upper(t1)) FROM tbl1}
219832508b7Sdrh} {this program is free software}
220832508b7Sdrhdo_test func-5.3 {
221832508b7Sdrh  execsql {SELECT upper(a), lower(a) FROM t2}
222832508b7Sdrh} {1 1 {} {} 345 345 {} {} 67890 67890}
2237de68a09Sdanielk1977ifcapable !icu {
224832508b7Sdrh  do_test func-5.4 {
225832508b7Sdrh    catchsql {SELECT upper(a,5) FROM t2}
226832508b7Sdrh  } {1 {wrong number of arguments to function upper()}}
2277de68a09Sdanielk1977}
228832508b7Sdrhdo_test func-5.5 {
229832508b7Sdrh  catchsql {SELECT upper(*) FROM t2}
230832508b7Sdrh} {1 {wrong number of arguments to function upper()}}
231832508b7Sdrh
232a9f9d1c0Sdrh# Test the coalesce() and nullif() functions
233832508b7Sdrh#
234832508b7Sdrhdo_test func-6.1 {
235832508b7Sdrh  execsql {SELECT coalesce(a,'xyz') FROM t2}
236832508b7Sdrh} {1 xyz 345 xyz 67890}
237832508b7Sdrhdo_test func-6.2 {
238832508b7Sdrh  execsql {SELECT coalesce(upper(a),'nil') FROM t2}
239832508b7Sdrh} {1 nil 345 nil 67890}
240a9f9d1c0Sdrhdo_test func-6.3 {
241a9f9d1c0Sdrh  execsql {SELECT coalesce(nullif(1,1),'nil')}
242a9f9d1c0Sdrh} {nil}
243a9f9d1c0Sdrhdo_test func-6.4 {
244a9f9d1c0Sdrh  execsql {SELECT coalesce(nullif(1,2),'nil')}
245a9f9d1c0Sdrh} {1}
246a9f9d1c0Sdrhdo_test func-6.5 {
247a9f9d1c0Sdrh  execsql {SELECT coalesce(nullif(1,NULL),'nil')}
248a9f9d1c0Sdrh} {1}
249a9f9d1c0Sdrh
250832508b7Sdrh
2516ed41ad7Sdrh# Test the last_insert_rowid() function
2526ed41ad7Sdrh#
2536ed41ad7Sdrhdo_test func-7.1 {
2546ed41ad7Sdrh  execsql {SELECT last_insert_rowid()}
2556ed41ad7Sdrh} [db last_insert_rowid]
2566ed41ad7Sdrh
257739105c7Sdrh# Tests for aggregate functions and how they handle NULLs.
258739105c7Sdrh#
259739105c7Sdrhdo_test func-8.1 {
2604489f9bdSdanielk1977  ifcapable explain {
261c5cdca61Sdrh    execsql {EXPLAIN SELECT sum(a) FROM t2;}
2624489f9bdSdanielk1977  }
263739105c7Sdrh  execsql {
264739105c7Sdrh    SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2;
265739105c7Sdrh  }
2663d1d95e6Sdrh} {68236 3 22745.33 1 67890 5}
267a9f9d1c0Sdrhdo_test func-8.2 {
268a9f9d1c0Sdrh  execsql {
269a9f9d1c0Sdrh    SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2;
270a9f9d1c0Sdrh  }
271a9f9d1c0Sdrh} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
27253c0f748Sdanielk1977
27353c0f748Sdanielk1977ifcapable tempdb {
274a9f9d1c0Sdrh  do_test func-8.3 {
275a9f9d1c0Sdrh    execsql {
276a9f9d1c0Sdrh      CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
277a9f9d1c0Sdrh      SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
278a9f9d1c0Sdrh    }
2799eb516c0Sdrh  } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
28053c0f748Sdanielk1977} else {
28153c0f748Sdanielk1977  do_test func-8.3 {
28253c0f748Sdanielk1977    execsql {
28353c0f748Sdanielk1977      CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC;
28453c0f748Sdanielk1977      SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
28553c0f748Sdanielk1977    }
28653c0f748Sdanielk1977  } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
28753c0f748Sdanielk1977}
2883aeab9e4Sdanielk1977do_test func-8.4 {
2893aeab9e4Sdanielk1977  execsql {
2903aeab9e4Sdanielk1977    SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3;
2913aeab9e4Sdanielk1977  }
2923aeab9e4Sdanielk1977} {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP}
293de3e41e3Sdanielk1977ifcapable compound {
29485e9e22bSdrh  do_test func-8.5 {
29585e9e22bSdrh    execsql {
29685e9e22bSdrh      SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x
29785e9e22bSdrh                          UNION ALL SELECT -9223372036854775807)
29885e9e22bSdrh    }
29985e9e22bSdrh  } {0}
30085e9e22bSdrh  do_test func-8.6 {
30185e9e22bSdrh    execsql {
30206a0a81cSdrh      SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x
30306a0a81cSdrh                          UNION ALL SELECT -9223372036854775807)
30406a0a81cSdrh    }
30506a0a81cSdrh  } {integer}
30606a0a81cSdrh  do_test func-8.7 {
30706a0a81cSdrh    execsql {
30801859b0bSdrh      SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x
30985e9e22bSdrh                          UNION ALL SELECT -9223372036854775807)
31085e9e22bSdrh    }
31101859b0bSdrh  } {real}
31206a0a81cSdrh  do_test func-8.8 {
31301859b0bSdrh    execsql {
31406a0a81cSdrh      SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x
31501859b0bSdrh                          UNION ALL SELECT -9223372036850000000)
31601859b0bSdrh    }
31706a0a81cSdrh  } {1}
318de3e41e3Sdanielk1977}
319739105c7Sdrh
320a9f9d1c0Sdrh# How do you test the random() function in a meaningful, deterministic way?
321a9f9d1c0Sdrh#
322a9f9d1c0Sdrhdo_test func-9.1 {
323a9f9d1c0Sdrh  execsql {
324a9f9d1c0Sdrh    SELECT random() is not null;
325a9f9d1c0Sdrh  }
326a9f9d1c0Sdrh} {1}
32763cf66f0Sdrhdo_test func-9.2 {
32863cf66f0Sdrh  execsql {
32963cf66f0Sdrh    SELECT typeof(random());
33063cf66f0Sdrh  }
33163cf66f0Sdrh} {integer}
33263cf66f0Sdrhdo_test func-9.3 {
33363cf66f0Sdrh  execsql {
334137c728fSdrh    SELECT randomblob(32) is not null;
33563cf66f0Sdrh  }
33663cf66f0Sdrh} {1}
33763cf66f0Sdrhdo_test func-9.4 {
33863cf66f0Sdrh  execsql {
339137c728fSdrh    SELECT typeof(randomblob(32));
34063cf66f0Sdrh  }
341137c728fSdrh} {blob}
34263cf66f0Sdrhdo_test func-9.5 {
34363cf66f0Sdrh  execsql {
344137c728fSdrh    SELECT length(randomblob(32)), length(randomblob(-5)),
345137c728fSdrh           length(randomblob(2000))
34663cf66f0Sdrh  }
347137c728fSdrh} {32 1 2000}
34863cf66f0Sdrh
349137c728fSdrh# The "hex()" function was added in order to be able to render blobs
350137c728fSdrh# generated by randomblob().  So this seems like a good place to test
351137c728fSdrh# hex().
352137c728fSdrh#
3534152e677Sdanielk1977ifcapable bloblit {
354137c728fSdrh  do_test func-9.10 {
355137c728fSdrh    execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')}
356137c728fSdrh  } {00112233445566778899AABBCCDDEEFF}
3574152e677Sdanielk1977}
358056c8f78Sdrhset encoding [db one {PRAGMA encoding}]
359056c8f78Sdrhif {$encoding=="UTF-16le"} {
360056c8f78Sdrh  do_test func-9.11-utf16le {
3611eb2538aSdrh    execsql {SELECT hex(replace('abcdefg','ef','12'))}
362056c8f78Sdrh  } {6100620063006400310032006700}
363056c8f78Sdrh  do_test func-9.12-utf16le {
364709cff33Sdrh    execsql {SELECT hex(replace('abcdefg','','12'))}
365709cff33Sdrh  } {{}}
366056c8f78Sdrh  do_test func-9.13-utf16le {
367056c8f78Sdrh    execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
368056c8f78Sdrh  } {610061006100610061006100620063006400650066006700}
369056c8f78Sdrh} elseif {$encoding=="UTF-8"} {
370056c8f78Sdrh  do_test func-9.11-utf8 {
371056c8f78Sdrh    execsql {SELECT hex(replace('abcdefg','ef','12'))}
372056c8f78Sdrh  } {61626364313267}
373056c8f78Sdrh  do_test func-9.12-utf8 {
374056c8f78Sdrh    execsql {SELECT hex(replace('abcdefg','','12'))}
375056c8f78Sdrh  } {{}}
376056c8f78Sdrh  do_test func-9.13-utf8 {
377709cff33Sdrh    execsql {SELECT hex(replace('aabcdefg','a','aaa'))}
378709cff33Sdrh  } {616161616161626364656667}
379056c8f78Sdrh}
380bf4133cbSdrh
3816cbe1f1bSdrh# Use the "sqlite_register_test_function" TCL command which is part of
3826cbe1f1bSdrh# the text fixture in order to verify correct operation of some of
3836cbe1f1bSdrh# the user-defined SQL function APIs that are not used by the built-in
3846cbe1f1bSdrh# functions.
3856cbe1f1bSdrh#
386dddca286Sdrhset ::DB [sqlite3_connection_pointer db]
3876cbe1f1bSdrhsqlite_register_test_function $::DB testfunc
3886cbe1f1bSdrhdo_test func-10.1 {
3896cbe1f1bSdrh  catchsql {
3906cbe1f1bSdrh    SELECT testfunc(NULL,NULL);
3916cbe1f1bSdrh  }
3926d88bad4Sdanielk1977} {1 {first argument should be one of: int int64 string double null value}}
3936cbe1f1bSdrhdo_test func-10.2 {
3946cbe1f1bSdrh  execsql {
3956cbe1f1bSdrh    SELECT testfunc(
3966cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
3976cbe1f1bSdrh     'int', 1234
3986cbe1f1bSdrh    );
3996cbe1f1bSdrh  }
4006cbe1f1bSdrh} {1234}
4016cbe1f1bSdrhdo_test func-10.3 {
4026cbe1f1bSdrh  execsql {
4036cbe1f1bSdrh    SELECT testfunc(
4046cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4056cbe1f1bSdrh     'string', NULL
4066cbe1f1bSdrh    );
4076cbe1f1bSdrh  }
4086cbe1f1bSdrh} {{}}
4096cbe1f1bSdrhdo_test func-10.4 {
4106cbe1f1bSdrh  execsql {
4116cbe1f1bSdrh    SELECT testfunc(
4126cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4136cbe1f1bSdrh     'double', 1.234
4146cbe1f1bSdrh    );
4156cbe1f1bSdrh  }
4166cbe1f1bSdrh} {1.234}
4176cbe1f1bSdrhdo_test func-10.5 {
4186cbe1f1bSdrh  execsql {
4196cbe1f1bSdrh    SELECT testfunc(
4206cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4216cbe1f1bSdrh     'int', 1234,
4226cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4236cbe1f1bSdrh     'string', NULL,
4246cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4256cbe1f1bSdrh     'double', 1.234,
4266cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4276cbe1f1bSdrh     'int', 1234,
4286cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4296cbe1f1bSdrh     'string', NULL,
4306cbe1f1bSdrh     'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
4316cbe1f1bSdrh     'double', 1.234
4326cbe1f1bSdrh    );
4336cbe1f1bSdrh  }
4346cbe1f1bSdrh} {1.234}
4356cbe1f1bSdrh
436647cb0e1Sdrh# Test the built-in sqlite_version(*) SQL function.
437647cb0e1Sdrh#
438647cb0e1Sdrhdo_test func-11.1 {
439647cb0e1Sdrh  execsql {
440647cb0e1Sdrh    SELECT sqlite_version(*);
441647cb0e1Sdrh  }
442ef4ac8f9Sdrh} [sqlite3 -version]
443647cb0e1Sdrh
444ef4ac8f9Sdrh# Test that destructors passed to sqlite3 by calls to sqlite3_result_text()
4453f6b0874Sdanielk1977# etc. are called. These tests use two special user-defined functions
4463f6b0874Sdanielk1977# (implemented in func.c) only available in test builds.
4473f6b0874Sdanielk1977#
4483f6b0874Sdanielk1977# Function test_destructor() takes one argument and returns a copy of the
4493f6b0874Sdanielk1977# text form of that argument. A destructor is associated with the return
4503f6b0874Sdanielk1977# value. Function test_destructor_count() returns the number of outstanding
4513f6b0874Sdanielk1977# destructor calls for values returned by test_destructor().
4523f6b0874Sdanielk1977#
453da84ca8dSdrhif {[db eval {PRAGMA encoding}]=="UTF-8"} {
454da84ca8dSdrh  do_test func-12.1-utf8 {
455d8123366Sdanielk1977    execsql {
456d8123366Sdanielk1977      SELECT test_destructor('hello world'), test_destructor_count();
457d8123366Sdanielk1977    }
458d8123366Sdanielk1977  } {{hello world} 1}
459da84ca8dSdrh} else {
4602a5fc4d6Sshane    ifcapable {utf16} {
461da84ca8dSdrh      do_test func-12.1-utf16 {
462da84ca8dSdrh        execsql {
463da84ca8dSdrh          SELECT test_destructor16('hello world'), test_destructor_count();
464da84ca8dSdrh        }
465da84ca8dSdrh      } {{hello world} 1}
466da84ca8dSdrh    }
4672a5fc4d6Sshane}
468d8123366Sdanielk1977do_test func-12.2 {
469d8123366Sdanielk1977  execsql {
470d8123366Sdanielk1977    SELECT test_destructor_count();
471d8123366Sdanielk1977  }
472d8123366Sdanielk1977} {0}
473d8123366Sdanielk1977do_test func-12.3 {
474d8123366Sdanielk1977  execsql {
4752dcef11bSdrh    SELECT test_destructor('hello')||' world'
476d8123366Sdanielk1977  }
4772dcef11bSdrh} {{hello world}}
478d8123366Sdanielk1977do_test func-12.4 {
479d8123366Sdanielk1977  execsql {
480d8123366Sdanielk1977    SELECT test_destructor_count();
481d8123366Sdanielk1977  }
482d8123366Sdanielk1977} {0}
483d8123366Sdanielk1977do_test func-12.5 {
484d8123366Sdanielk1977  execsql {
485d8123366Sdanielk1977    CREATE TABLE t4(x);
486d8123366Sdanielk1977    INSERT INTO t4 VALUES(test_destructor('hello'));
487d8123366Sdanielk1977    INSERT INTO t4 VALUES(test_destructor('world'));
488d8123366Sdanielk1977    SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4;
489d8123366Sdanielk1977  }
490d8123366Sdanielk1977} {hello world}
491d8123366Sdanielk1977do_test func-12.6 {
492d8123366Sdanielk1977  execsql {
493d8123366Sdanielk1977    SELECT test_destructor_count();
494d8123366Sdanielk1977  }
495d8123366Sdanielk1977} {0}
4963f6b0874Sdanielk1977do_test func-12.7 {
4973f6b0874Sdanielk1977  execsql {
4983f6b0874Sdanielk1977    DROP TABLE t4;
4993f6b0874Sdanielk1977  }
5003f6b0874Sdanielk1977} {}
5013f6b0874Sdanielk1977
502a4e5d58fSdrh
5033f6b0874Sdanielk1977# Test that the auxdata API for scalar functions works. This test uses
5043f6b0874Sdanielk1977# a special user-defined function only available in test builds,
5053f6b0874Sdanielk1977# test_auxdata(). Function test_auxdata() takes any number of arguments.
5063f6b0874Sdanielk1977do_test func-13.1 {
5073f6b0874Sdanielk1977  execsql {
5083f6b0874Sdanielk1977    SELECT test_auxdata('hello world');
5093f6b0874Sdanielk1977  }
5103f6b0874Sdanielk1977} {0}
511ece80f1eSdanielk1977
5123f6b0874Sdanielk1977do_test func-13.2 {
5133f6b0874Sdanielk1977  execsql {
5143f6b0874Sdanielk1977    CREATE TABLE t4(a, b);
5153f6b0874Sdanielk1977    INSERT INTO t4 VALUES('abc', 'def');
5163f6b0874Sdanielk1977    INSERT INTO t4 VALUES('ghi', 'jkl');
5173f6b0874Sdanielk1977  }
5183f6b0874Sdanielk1977} {}
5193f6b0874Sdanielk1977do_test func-13.3 {
5203f6b0874Sdanielk1977  execsql {
5213f6b0874Sdanielk1977    SELECT test_auxdata('hello world') FROM t4;
5223f6b0874Sdanielk1977  }
5233f6b0874Sdanielk1977} {0 1}
5243f6b0874Sdanielk1977do_test func-13.4 {
5253f6b0874Sdanielk1977  execsql {
5263f6b0874Sdanielk1977    SELECT test_auxdata('hello world', 123) FROM t4;
5273f6b0874Sdanielk1977  }
5283f6b0874Sdanielk1977} {{0 0} {1 1}}
5293f6b0874Sdanielk1977do_test func-13.5 {
5303f6b0874Sdanielk1977  execsql {
5313f6b0874Sdanielk1977    SELECT test_auxdata('hello world', a) FROM t4;
5323f6b0874Sdanielk1977  }
5333f6b0874Sdanielk1977} {{0 0} {1 0}}
5343f6b0874Sdanielk1977do_test func-13.6 {
5353f6b0874Sdanielk1977  execsql {
5363f6b0874Sdanielk1977    SELECT test_auxdata('hello'||'world', a) FROM t4;
5373f6b0874Sdanielk1977  }
5383f6b0874Sdanielk1977} {{0 0} {1 0}}
5393f6b0874Sdanielk1977
5403f6b0874Sdanielk1977# Test that auxilary data is preserved between calls for SQL variables.
5413f6b0874Sdanielk1977do_test func-13.7 {
542dddca286Sdrh  set DB [sqlite3_connection_pointer db]
5433f6b0874Sdanielk1977  set sql "SELECT test_auxdata( ? , a ) FROM t4;"
5443f6b0874Sdanielk1977  set STMT [sqlite3_prepare $DB $sql -1 TAIL]
54510dfbbb5Sdrh  sqlite3_bind_text $STMT 1 hello\000 -1
5463f6b0874Sdanielk1977  set res [list]
5473f6b0874Sdanielk1977  while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
5483f6b0874Sdanielk1977    lappend res [sqlite3_column_text $STMT 0]
5493f6b0874Sdanielk1977  }
5503f6b0874Sdanielk1977  lappend res [sqlite3_finalize $STMT]
5513f6b0874Sdanielk1977} {{0 0} {1 0} SQLITE_OK}
552d8123366Sdanielk1977
553312d6b36Sdanielk1977# Make sure that a function with a very long name is rejected
554312d6b36Sdanielk1977do_test func-14.1 {
555312d6b36Sdanielk1977  catch {
556312d6b36Sdanielk1977    db function [string repeat X 254] {return "hello"}
557312d6b36Sdanielk1977  }
558312d6b36Sdanielk1977} {0}
559312d6b36Sdanielk1977do_test func-14.2 {
560312d6b36Sdanielk1977  catch {
561312d6b36Sdanielk1977    db function [string repeat X 256] {return "hello"}
562312d6b36Sdanielk1977  }
563312d6b36Sdanielk1977} {1}
564312d6b36Sdanielk1977
56501427a62Sdanielk1977do_test func-15.1 {
56600e087b2Sdrh  catchsql {select test_error(NULL)}
56790669c1dSdrh} {1 {}}
56800e087b2Sdrhdo_test func-15.2 {
56900e087b2Sdrh  catchsql {select test_error('this is the error message')}
57000e087b2Sdrh} {1 {this is the error message}}
57100e087b2Sdrhdo_test func-15.3 {
57200e087b2Sdrh  catchsql {select test_error('this is the error message',12)}
57300e087b2Sdrh} {1 {this is the error message}}
57400e087b2Sdrhdo_test func-15.4 {
57500e087b2Sdrh  db errorcode
57600e087b2Sdrh} {12}
57701427a62Sdanielk1977
578576ec6b3Sdanielk1977# Test the quote function for BLOB and NULL values.
579576ec6b3Sdanielk1977do_test func-16.1 {
580576ec6b3Sdanielk1977  execsql {
581576ec6b3Sdanielk1977    CREATE TABLE tbl2(a, b);
582576ec6b3Sdanielk1977  }
583576ec6b3Sdanielk1977  set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL]
584576ec6b3Sdanielk1977  sqlite3_bind_blob $::STMT 1 abc 3
585576ec6b3Sdanielk1977  sqlite3_step $::STMT
586576ec6b3Sdanielk1977  sqlite3_finalize $::STMT
587576ec6b3Sdanielk1977  execsql {
588576ec6b3Sdanielk1977    SELECT quote(a), quote(b) FROM tbl2;
589576ec6b3Sdanielk1977  }
590576ec6b3Sdanielk1977} {X'616263' NULL}
591576ec6b3Sdanielk1977
5922501eb1dSdrh# Correctly handle function error messages that include %.  Ticket #1354
5932501eb1dSdrh#
5942501eb1dSdrhdo_test func-17.1 {
5952501eb1dSdrh  proc testfunc1 args {error "Error %d with %s percents %p"}
5962501eb1dSdrh  db function testfunc1 ::testfunc1
5972501eb1dSdrh  catchsql {
5982501eb1dSdrh    SELECT testfunc1(1,2,3);
5992501eb1dSdrh  }
6002501eb1dSdrh} {1 {Error %d with %s percents %p}}
6012501eb1dSdrh
6023d1d95e6Sdrh# The SUM function should return integer results when all inputs are integer.
6033d1d95e6Sdrh#
6043d1d95e6Sdrhdo_test func-18.1 {
6053d1d95e6Sdrh  execsql {
6063d1d95e6Sdrh    CREATE TABLE t5(x);
6073d1d95e6Sdrh    INSERT INTO t5 VALUES(1);
6083d1d95e6Sdrh    INSERT INTO t5 VALUES(-99);
6093d1d95e6Sdrh    INSERT INTO t5 VALUES(10000);
6103d1d95e6Sdrh    SELECT sum(x) FROM t5;
6113d1d95e6Sdrh  }
6123d1d95e6Sdrh} {9902}
6133d1d95e6Sdrhdo_test func-18.2 {
6143d1d95e6Sdrh  execsql {
6153d1d95e6Sdrh    INSERT INTO t5 VALUES(0.0);
6163d1d95e6Sdrh    SELECT sum(x) FROM t5;
6173d1d95e6Sdrh  }
6188a51256cSdrh} {9902.0}
619576ec6b3Sdanielk1977
620c2bd913aSdrh# The sum of nothing is NULL.  But the sum of all NULLs is NULL.
6213f219f46Sdrh#
62276c730c1Sdrh# The TOTAL of nothing is 0.0.
62376c730c1Sdrh#
6243f219f46Sdrhdo_test func-18.3 {
6253f219f46Sdrh  execsql {
6263f219f46Sdrh    DELETE FROM t5;
62776c730c1Sdrh    SELECT sum(x), total(x) FROM t5;
6283f219f46Sdrh  }
62976c730c1Sdrh} {{} 0.0}
6303f219f46Sdrhdo_test func-18.4 {
6313f219f46Sdrh  execsql {
6323f219f46Sdrh    INSERT INTO t5 VALUES(NULL);
63376c730c1Sdrh    SELECT sum(x), total(x) FROM t5
6343f219f46Sdrh  }
63576c730c1Sdrh} {{} 0.0}
6363f219f46Sdrhdo_test func-18.5 {
6373f219f46Sdrh  execsql {
6383f219f46Sdrh    INSERT INTO t5 VALUES(NULL);
63976c730c1Sdrh    SELECT sum(x), total(x) FROM t5
6403f219f46Sdrh  }
64176c730c1Sdrh} {{} 0.0}
6423f219f46Sdrhdo_test func-18.6 {
6433f219f46Sdrh  execsql {
6443f219f46Sdrh    INSERT INTO t5 VALUES(123);
64576c730c1Sdrh    SELECT sum(x), total(x) FROM t5
6463f219f46Sdrh  }
64776c730c1Sdrh} {123 123.0}
6485708d2deSdrh
6498c08e861Sdrh# Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes
6508c08e861Sdrh# an error. The non-standard TOTAL() function continues to give a helpful
6518c08e861Sdrh# result.
652fc6ad39cSdrh#
653fc6ad39cSdrhdo_test func-18.10 {
654fc6ad39cSdrh  execsql {
655fc6ad39cSdrh    CREATE TABLE t6(x INTEGER);
656fc6ad39cSdrh    INSERT INTO t6 VALUES(1);
657fc6ad39cSdrh    INSERT INTO t6 VALUES(1<<62);
658fc6ad39cSdrh    SELECT sum(x) - ((1<<62)+1) from t6;
659fc6ad39cSdrh  }
660fc6ad39cSdrh} 0
66176c730c1Sdrhdo_test func-18.11 {
66276c730c1Sdrh  execsql {
66376c730c1Sdrh    SELECT typeof(sum(x)) FROM t6
66476c730c1Sdrh  }
66576c730c1Sdrh} integer
66676c730c1Sdrhdo_test func-18.12 {
6678c08e861Sdrh  catchsql {
66876c730c1Sdrh    INSERT INTO t6 VALUES(1<<62);
66976c730c1Sdrh    SELECT sum(x) - ((1<<62)*2.0+1) from t6;
67076c730c1Sdrh  }
6718c08e861Sdrh} {1 {integer overflow}}
67276c730c1Sdrhdo_test func-18.13 {
67376c730c1Sdrh  execsql {
67476c730c1Sdrh    SELECT total(x) - ((1<<62)*2.0+1) FROM t6
67576c730c1Sdrh  }
67676c730c1Sdrh} 0.0
6778c08e861Sdrhdo_test func-18.14 {
6788c08e861Sdrh  execsql {
6798c08e861Sdrh    SELECT sum(-9223372036854775805);
6808c08e861Sdrh  }
6818c08e861Sdrh} -9223372036854775805
6824b2688abSdanielk1977
6834b2688abSdanielk1977ifcapable compound&&subquery {
6844b2688abSdanielk1977
6858c08e861Sdrhdo_test func-18.15 {
6868c08e861Sdrh  catchsql {
6878c08e861Sdrh    SELECT sum(x) FROM
6888c08e861Sdrh       (SELECT 9223372036854775807 AS x UNION ALL
6898c08e861Sdrh        SELECT 10 AS x);
6908c08e861Sdrh  }
6918c08e861Sdrh} {1 {integer overflow}}
6928c08e861Sdrhdo_test func-18.16 {
6938c08e861Sdrh  catchsql {
6948c08e861Sdrh    SELECT sum(x) FROM
6958c08e861Sdrh       (SELECT 9223372036854775807 AS x UNION ALL
6968c08e861Sdrh        SELECT -10 AS x);
6978c08e861Sdrh  }
6988c08e861Sdrh} {0 9223372036854775797}
6998c08e861Sdrhdo_test func-18.17 {
7008c08e861Sdrh  catchsql {
7018c08e861Sdrh    SELECT sum(x) FROM
7028c08e861Sdrh       (SELECT -9223372036854775807 AS x UNION ALL
7038c08e861Sdrh        SELECT 10 AS x);
7048c08e861Sdrh  }
7058c08e861Sdrh} {0 -9223372036854775797}
7068c08e861Sdrhdo_test func-18.18 {
7078c08e861Sdrh  catchsql {
7088c08e861Sdrh    SELECT sum(x) FROM
7098c08e861Sdrh       (SELECT -9223372036854775807 AS x UNION ALL
7108c08e861Sdrh        SELECT -10 AS x);
7118c08e861Sdrh  }
7128c08e861Sdrh} {1 {integer overflow}}
7138c08e861Sdrhdo_test func-18.19 {
7148c08e861Sdrh  catchsql {
7158c08e861Sdrh    SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x);
7168c08e861Sdrh  }
7178c08e861Sdrh} {0 -1}
7188c08e861Sdrhdo_test func-18.20 {
7198c08e861Sdrh  catchsql {
7208c08e861Sdrh    SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x);
7218c08e861Sdrh  }
7228c08e861Sdrh} {0 1}
7238c08e861Sdrhdo_test func-18.21 {
7248c08e861Sdrh  catchsql {
7258c08e861Sdrh    SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x);
7268c08e861Sdrh  }
7278c08e861Sdrh} {0 -1}
7288c08e861Sdrhdo_test func-18.22 {
7298c08e861Sdrh  catchsql {
7308c08e861Sdrh    SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x);
7318c08e861Sdrh  }
7328c08e861Sdrh} {0 1}
73376c730c1Sdrh
7344b2688abSdanielk1977} ;# ifcapable compound&&subquery
7354b2688abSdanielk1977
73652fc849aSdrh# Integer overflow on abs()
73752fc849aSdrh#
73852fc849aSdrhdo_test func-18.31 {
73952fc849aSdrh  catchsql {
74052fc849aSdrh    SELECT abs(-9223372036854775807);
74152fc849aSdrh  }
74252fc849aSdrh} {0 9223372036854775807}
74352fc849aSdrhdo_test func-18.32 {
74452fc849aSdrh  catchsql {
74552fc849aSdrh    SELECT abs(-9223372036854775807-1);
74652fc849aSdrh  }
74752fc849aSdrh} {1 {integer overflow}}
74852fc849aSdrh
7497f375901Sdrh# The MATCH function exists but is only a stub and always throws an error.
7507f375901Sdrh#
7517f375901Sdrhdo_test func-19.1 {
7527f375901Sdrh  execsql {
7537f375901Sdrh    SELECT match(a,b) FROM t1 WHERE 0;
7547f375901Sdrh  }
7557f375901Sdrh} {}
7567f375901Sdrhdo_test func-19.2 {
7577f375901Sdrh  catchsql {
7587f375901Sdrh    SELECT 'abc' MATCH 'xyz';
7597f375901Sdrh  }
760b7481e70Sdrh} {1 {unable to use function MATCH in the requested context}}
7617f375901Sdrhdo_test func-19.3 {
7627f375901Sdrh  catchsql {
7637f375901Sdrh    SELECT 'abc' NOT MATCH 'xyz';
7647f375901Sdrh  }
765b7481e70Sdrh} {1 {unable to use function MATCH in the requested context}}
7667f375901Sdrhdo_test func-19.4 {
7677f375901Sdrh  catchsql {
7687f375901Sdrh    SELECT match(1,2,3);
7697f375901Sdrh  }
7707f375901Sdrh} {1 {wrong number of arguments to function match()}}
77176c730c1Sdrh
772bdf67e0eSdrh# Soundex tests.
773bdf67e0eSdrh#
774bdf67e0eSdrhif {![catch {db eval {SELECT soundex('hello')}}]} {
775bdf67e0eSdrh  set i 0
776bdf67e0eSdrh  foreach {name sdx} {
777bdf67e0eSdrh    euler        E460
778bdf67e0eSdrh    EULER        E460
779bdf67e0eSdrh    Euler        E460
780bdf67e0eSdrh    ellery       E460
781bdf67e0eSdrh    gauss        G200
782bdf67e0eSdrh    ghosh        G200
783bdf67e0eSdrh    hilbert      H416
784bdf67e0eSdrh    Heilbronn    H416
785bdf67e0eSdrh    knuth        K530
786bdf67e0eSdrh    kant         K530
787bdf67e0eSdrh    Lloyd        L300
788bdf67e0eSdrh    LADD         L300
789bdf67e0eSdrh    Lukasiewicz  L222
790bdf67e0eSdrh    Lissajous    L222
791bdf67e0eSdrh    A            A000
792bdf67e0eSdrh    12345        ?000
793bdf67e0eSdrh  } {
794bdf67e0eSdrh    incr i
795bdf67e0eSdrh    do_test func-20.$i {
796bdf67e0eSdrh      execsql {SELECT soundex($name)}
797bdf67e0eSdrh    } $sdx
798bdf67e0eSdrh  }
799bdf67e0eSdrh}
800bdf67e0eSdrh
80126b6d90dSdrh# Tests of the REPLACE function.
80226b6d90dSdrh#
80326b6d90dSdrhdo_test func-21.1 {
80426b6d90dSdrh  catchsql {
80526b6d90dSdrh    SELECT replace(1,2);
80626b6d90dSdrh  }
80726b6d90dSdrh} {1 {wrong number of arguments to function replace()}}
80826b6d90dSdrhdo_test func-21.2 {
80926b6d90dSdrh  catchsql {
81026b6d90dSdrh    SELECT replace(1,2,3,4);
81126b6d90dSdrh  }
81226b6d90dSdrh} {1 {wrong number of arguments to function replace()}}
81326b6d90dSdrhdo_test func-21.3 {
81426b6d90dSdrh  execsql {
81526b6d90dSdrh    SELECT typeof(replace("This is the main test string", NULL, "ALT"));
81626b6d90dSdrh  }
81726b6d90dSdrh} {null}
81826b6d90dSdrhdo_test func-21.4 {
81926b6d90dSdrh  execsql {
82026b6d90dSdrh    SELECT typeof(replace(NULL, "main", "ALT"));
82126b6d90dSdrh  }
82226b6d90dSdrh} {null}
82326b6d90dSdrhdo_test func-21.5 {
82426b6d90dSdrh  execsql {
82526b6d90dSdrh    SELECT typeof(replace("This is the main test string", "main", NULL));
82626b6d90dSdrh  }
82726b6d90dSdrh} {null}
82826b6d90dSdrhdo_test func-21.6 {
82926b6d90dSdrh  execsql {
83026b6d90dSdrh    SELECT replace("This is the main test string", "main", "ALT");
83126b6d90dSdrh  }
83226b6d90dSdrh} {{This is the ALT test string}}
83326b6d90dSdrhdo_test func-21.7 {
83426b6d90dSdrh  execsql {
83526b6d90dSdrh    SELECT replace("This is the main test string", "main", "larger-main");
83626b6d90dSdrh  }
83726b6d90dSdrh} {{This is the larger-main test string}}
83826b6d90dSdrhdo_test func-21.8 {
83926b6d90dSdrh  execsql {
84026b6d90dSdrh    SELECT replace("aaaaaaa", "a", "0123456789");
84126b6d90dSdrh  }
84226b6d90dSdrh} {0123456789012345678901234567890123456789012345678901234567890123456789}
84326b6d90dSdrh
8444152e677Sdanielk1977ifcapable tclvar {
84517374e8fSdanielk1977  do_test func-21.9 {
84617374e8fSdanielk1977    # Attempt to exploit a buffer-overflow that at one time existed
84717374e8fSdanielk1977    # in the REPLACE function.
84817374e8fSdanielk1977    set ::str "[string repeat A 29998]CC[string repeat A 35537]"
84917374e8fSdanielk1977    set ::rep [string repeat B 65536]
85017374e8fSdanielk1977    execsql {
85117374e8fSdanielk1977      SELECT LENGTH(REPLACE($::str, 'C', $::rep));
85217374e8fSdanielk1977    }
85317374e8fSdanielk1977  } [expr 29998 + 2*65536 + 35537]
8544152e677Sdanielk1977}
85517374e8fSdanielk1977
856309b3386Sdrh# Tests for the TRIM, LTRIM and RTRIM functions.
857309b3386Sdrh#
858309b3386Sdrhdo_test func-22.1 {
859309b3386Sdrh  catchsql {SELECT trim(1,2,3)}
860309b3386Sdrh} {1 {wrong number of arguments to function trim()}}
861309b3386Sdrhdo_test func-22.2 {
862309b3386Sdrh  catchsql {SELECT ltrim(1,2,3)}
863309b3386Sdrh} {1 {wrong number of arguments to function ltrim()}}
864309b3386Sdrhdo_test func-22.3 {
865309b3386Sdrh  catchsql {SELECT rtrim(1,2,3)}
866309b3386Sdrh} {1 {wrong number of arguments to function rtrim()}}
867309b3386Sdrhdo_test func-22.4 {
868309b3386Sdrh  execsql {SELECT trim('  hi  ');}
869309b3386Sdrh} {hi}
870309b3386Sdrhdo_test func-22.5 {
871309b3386Sdrh  execsql {SELECT ltrim('  hi  ');}
872309b3386Sdrh} {{hi  }}
873309b3386Sdrhdo_test func-22.6 {
874309b3386Sdrh  execsql {SELECT rtrim('  hi  ');}
875309b3386Sdrh} {{  hi}}
876309b3386Sdrhdo_test func-22.7 {
877309b3386Sdrh  execsql {SELECT trim('  hi  ','xyz');}
878309b3386Sdrh} {{  hi  }}
879309b3386Sdrhdo_test func-22.8 {
880309b3386Sdrh  execsql {SELECT ltrim('  hi  ','xyz');}
881309b3386Sdrh} {{  hi  }}
882309b3386Sdrhdo_test func-22.9 {
883309b3386Sdrh  execsql {SELECT rtrim('  hi  ','xyz');}
884309b3386Sdrh} {{  hi  }}
885309b3386Sdrhdo_test func-22.10 {
886309b3386Sdrh  execsql {SELECT trim('xyxzy  hi  zzzy','xyz');}
887309b3386Sdrh} {{  hi  }}
888309b3386Sdrhdo_test func-22.11 {
889309b3386Sdrh  execsql {SELECT ltrim('xyxzy  hi  zzzy','xyz');}
890309b3386Sdrh} {{  hi  zzzy}}
891309b3386Sdrhdo_test func-22.12 {
892309b3386Sdrh  execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');}
893309b3386Sdrh} {{xyxzy  hi  }}
894309b3386Sdrhdo_test func-22.13 {
895309b3386Sdrh  execsql {SELECT trim('  hi  ','');}
896309b3386Sdrh} {{  hi  }}
8974e05c83bSdrhif {[db one {PRAGMA encoding}]=="UTF-8"} {
898d1e3a616Sdrh  do_test func-22.14 {
8997a928d75Sdrh    execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))}
9007a928d75Sdrh  } {F48FBFBF6869}
901d1e3a616Sdrh  do_test func-22.15 {
9027a928d75Sdrh    execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61',
9037a928d75Sdrh                             x'6162e1bfbfc280f48fbfbf'))}
904d1e3a616Sdrh  } {6869}
905d1e3a616Sdrh  do_test func-22.16 {
906d1e3a616Sdrh    execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));}
907d1e3a616Sdrh  } {CEB2CEB3}
9084e05c83bSdrh}
909309b3386Sdrhdo_test func-22.20 {
910309b3386Sdrh  execsql {SELECT typeof(trim(NULL));}
911309b3386Sdrh} {null}
912309b3386Sdrhdo_test func-22.21 {
913309b3386Sdrh  execsql {SELECT typeof(trim(NULL,'xyz'));}
914309b3386Sdrh} {null}
915309b3386Sdrhdo_test func-22.22 {
916309b3386Sdrh  execsql {SELECT typeof(trim('hello',NULL));}
917309b3386Sdrh} {null}
91826b6d90dSdrh
919fa18beceSdanielk1977# This is to test the deprecated sqlite3_aggregate_count() API.
920fa18beceSdanielk1977#
921eec556d3Sshaneifcapable deprecated {
922fa18beceSdanielk1977  do_test func-23.1 {
923fa18beceSdanielk1977    sqlite3_create_aggregate db
924fa18beceSdanielk1977    execsql {
925fa18beceSdanielk1977      SELECT legacy_count() FROM t6;
926fa18beceSdanielk1977    }
927fa18beceSdanielk1977  } {3}
928eec556d3Sshane}
929fa18beceSdanielk1977
930ade86483Sdrh# The group_concat() function.
931ade86483Sdrh#
932ade86483Sdrhdo_test func-24.1 {
933ade86483Sdrh  execsql {
934ade86483Sdrh    SELECT group_concat(t1) FROM tbl1
935ade86483Sdrh  }
936ade86483Sdrh} {this,program,is,free,software}
937ade86483Sdrhdo_test func-24.2 {
938ade86483Sdrh  execsql {
939ade86483Sdrh    SELECT group_concat(t1,' ') FROM tbl1
940ade86483Sdrh  }
941ade86483Sdrh} {{this program is free software}}
942ade86483Sdrhdo_test func-24.3 {
943ade86483Sdrh  execsql {
944ade86483Sdrh    SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1
945ade86483Sdrh  }
946ade86483Sdrh} {{this 2 program 3 is 4 free 5 software}}
947ade86483Sdrhdo_test func-24.4 {
948ade86483Sdrh  execsql {
949ade86483Sdrh    SELECT group_concat(NULL,t1) FROM tbl1
950ade86483Sdrh  }
951ade86483Sdrh} {{}}
952ade86483Sdrhdo_test func-24.5 {
953ade86483Sdrh  execsql {
954ade86483Sdrh    SELECT group_concat(t1,NULL) FROM tbl1
955ade86483Sdrh  }
956ade86483Sdrh} {thisprogramisfreesoftware}
9572dca8680Sdrhdo_test func-24.6 {
9582dca8680Sdrh  execsql {
9592dca8680Sdrh    SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
9602dca8680Sdrh  }
9612dca8680Sdrh} {BEGIN-this,program,is,free,software}
9623780b5deSdrhunset -nocomplain midargs
963a2baf3a2Sdrhset midargs {}
9643780b5deSdrhunset -nocomplain midres
965a2baf3a2Sdrhset midres {}
9663780b5deSdrhunset -nocomplain result
967a2baf3a2Sdrhfor {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]-1} {incr i} {
968a2baf3a2Sdrh  append midargs ,'/$i'
969a2baf3a2Sdrh  append midres /$i
970a2baf3a2Sdrh  set result \
971a2baf3a2Sdrh     "this$midres:program$midres:is$midres:free$midres:software$midres"
972a2baf3a2Sdrh  set sql "SELECT group_concat(t1$midargs,':') FROM tbl1"
973a2baf3a2Sdrh  do_test func-24.7.$i {
974a2baf3a2Sdrh     db eval $::sql
975a2baf3a2Sdrh  } $result
976a2baf3a2Sdrh}
977ade86483Sdrh
978191b54cbSdrh# Use the test_isolation function to make sure that type conversions
979191b54cbSdrh# on function arguments do not effect subsequent arguments.
980191b54cbSdrh#
981191b54cbSdrhdo_test func-25.1 {
982191b54cbSdrh  execsql {SELECT test_isolation(t1,t1) FROM tbl1}
983191b54cbSdrh} {this program is free software}
984191b54cbSdrh
98524b58dd7Sdrh# Try to misuse the sqlite3_create_function() interface.  Verify that
98624b58dd7Sdrh# errors are returned.
98724b58dd7Sdrh#
98824b58dd7Sdrhdo_test func-26.1 {
98924b58dd7Sdrh  abuse_create_function db
99024b58dd7Sdrh} {}
99124b58dd7Sdrh
99224b58dd7Sdrh# The previous test (func-26.1) registered a function with a very long
99324b58dd7Sdrh# function name that takes many arguments and always returns NULL.  Verify
99424b58dd7Sdrh# that this function works correctly.
99524b58dd7Sdrh#
99624b58dd7Sdrhdo_test func-26.2 {
99724b58dd7Sdrh  set a {}
99824b58dd7Sdrh  for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} {
99924b58dd7Sdrh    lappend a $i
100024b58dd7Sdrh  }
100124b58dd7Sdrh  db eval "
100224b58dd7Sdrh     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 ,]);
100324b58dd7Sdrh  "
100424b58dd7Sdrh} {{}}
100524b58dd7Sdrhdo_test func-26.3 {
100624b58dd7Sdrh  set a {}
100724b58dd7Sdrh  for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} {
100824b58dd7Sdrh    lappend a $i
100924b58dd7Sdrh  }
101024b58dd7Sdrh  catchsql "
101124b58dd7Sdrh     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 ,]);
101224b58dd7Sdrh  "
101324b58dd7Sdrh} {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}}
101424b58dd7Sdrhdo_test func-26.4 {
101524b58dd7Sdrh  set a {}
101624b58dd7Sdrh  for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} {
101724b58dd7Sdrh    lappend a $i
101824b58dd7Sdrh  }
101924b58dd7Sdrh  catchsql "
102024b58dd7Sdrh     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 ,]);
102124b58dd7Sdrh  "
102224b58dd7Sdrh} {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()}}
102324b58dd7Sdrhdo_test func-26.5 {
102424b58dd7Sdrh  catchsql "
102524b58dd7Sdrh     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);
102624b58dd7Sdrh  "
102724b58dd7Sdrh} {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}}
102824b58dd7Sdrhdo_test func-26.6 {
102924b58dd7Sdrh  catchsql "
103024b58dd7Sdrh     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);
103124b58dd7Sdrh  "
103224b58dd7Sdrh} {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}}
103324b58dd7Sdrh
1034*dfbc3a8aSdrhdo_test func-27.1 {
1035*dfbc3a8aSdrh  catchsql {SELECT coalesce()}
1036*dfbc3a8aSdrh} {1 {wrong number of arguments to function coalesce()}}
1037*dfbc3a8aSdrhdo_test func-27.2 {
1038*dfbc3a8aSdrh  catchsql {SELECT coalesce(1)}
1039*dfbc3a8aSdrh} {1 {wrong number of arguments to function coalesce()}}
1040*dfbc3a8aSdrhdo_test func-27.3 {
1041*dfbc3a8aSdrh  catchsql {SELECT coalesce(1,2)}
1042*dfbc3a8aSdrh} {0 1}
1043*dfbc3a8aSdrh
10445708d2deSdrhfinish_test
1045