| OLD | NEW | 
 | (Empty) | 
|     1 # 2001 September 15 |  | 
|     2 # |  | 
|     3 # The author disclaims copyright to this source code.  In place of |  | 
|     4 # a legal notice, here is a blessing: |  | 
|     5 # |  | 
|     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. |  | 
|     9 # |  | 
|    10 #*********************************************************************** |  | 
|    11 # This file implements regression tests for SQLite library.  The |  | 
|    12 # focus of this file is testing built-in functions. |  | 
|    13 # |  | 
|    14  |  | 
|    15 set testdir [file dirname $argv0] |  | 
|    16 source $testdir/tester.tcl |  | 
|    17  |  | 
|    18 # Create a table to work with. |  | 
|    19 # |  | 
|    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} |  | 
|    38  |  | 
|    39 # Check out the length() function |  | 
|    40 # |  | 
|    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} |  | 
|    59  |  | 
|    60 # Check out the substr() function |  | 
|    61 # |  | 
|    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} |  | 
|    95  |  | 
|    96 # Only do the following tests if TCL has UTF-8 capabilities |  | 
|    97 # |  | 
|    98 if {"\u1234"!="u1234"} { |  | 
|    99  |  | 
|   100 # Put some UTF-8 characters in the database |  | 
|   101 # |  | 
|   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} |  | 
|   146  |  | 
|   147 } ;# End \u1234!=u1234 |  | 
|   148  |  | 
|   149 # Test the abs() and round() functions. |  | 
|   150 # |  | 
|   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()}} |  | 
|   161 } |  | 
|   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()}} |  | 
|   172 } |  | 
|   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}} |  | 
|   183 } |  | 
|   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}} |  | 
|   193 } |  | 
|   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} |  | 
|   200  |  | 
|   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 } |  | 
|   239  |  | 
|   240 # Test the upper() and lower() functions |  | 
|   241 # |  | 
|   242 do_test func-5.1 { |  | 
|   243   execsql {SELECT upper(t1) FROM tbl1} |  | 
|   244 } {THIS PROGRAM IS FREE SOFTWARE} |  | 
|   245 do_test func-5.2 { |  | 
|   246   execsql {SELECT lower(upper(t1)) FROM tbl1} |  | 
|   247 } {this program is free software} |  | 
|   248 do_test func-5.3 { |  | 
|   249   execsql {SELECT upper(a), lower(a) FROM t2} |  | 
|   250 } {1 1 {} {} 345 345 {} {} 67890 67890} |  | 
|   251 ifcapable !icu { |  | 
|   252   do_test func-5.4 { |  | 
|   253     catchsql {SELECT upper(a,5) FROM t2} |  | 
|   254   } {1 {wrong number of arguments to function upper()}} |  | 
|   255 } |  | 
|   256 do_test func-5.5 { |  | 
|   257   catchsql {SELECT upper(*) FROM t2} |  | 
|   258 } {1 {wrong number of arguments to function upper()}} |  | 
|   259  |  | 
|   260 # Test the coalesce() and nullif() functions |  | 
|   261 # |  | 
|   262 do_test func-6.1 { |  | 
|   263   execsql {SELECT coalesce(a,'xyz') FROM t2} |  | 
|   264 } {1 xyz 345 xyz 67890} |  | 
|   265 do_test func-6.2 { |  | 
|   266   execsql {SELECT coalesce(upper(a),'nil') FROM t2} |  | 
|   267 } {1 nil 345 nil 67890} |  | 
|   268 do_test func-6.3 { |  | 
|   269   execsql {SELECT coalesce(nullif(1,1),'nil')} |  | 
|   270 } {nil} |  | 
|   271 do_test func-6.4 { |  | 
|   272   execsql {SELECT coalesce(nullif(1,2),'nil')} |  | 
|   273 } {1} |  | 
|   274 do_test func-6.5 { |  | 
|   275   execsql {SELECT coalesce(nullif(1,NULL),'nil')} |  | 
|   276 } {1} |  | 
|   277  |  | 
|   278  |  | 
|   279 # Test the last_insert_rowid() function |  | 
|   280 # |  | 
|   281 do_test func-7.1 { |  | 
|   282   execsql {SELECT last_insert_rowid()} |  | 
|   283 } [db last_insert_rowid] |  | 
|   284  |  | 
|   285 # Tests for aggregate functions and how they handle NULLs. |  | 
|   286 # |  | 
|   287 ifcapable floatingpoint { |  | 
|   288   do_test func-8.1 { |  | 
|   289     ifcapable explain { |  | 
|   290       execsql {EXPLAIN SELECT sum(a) FROM t2;} |  | 
|   291     } |  | 
|   292     execsql { |  | 
|   293       SELECT sum(a), count(a), round(avg(a),2), min(a), max(a), count(*) FROM t2
      ; |  | 
|   294     } |  | 
|   295   } {68236 3 22745.33 1 67890 5} |  | 
|   296 } |  | 
|   297 ifcapable !floatingpoint { |  | 
|   298   do_test func-8.1 { |  | 
|   299     ifcapable explain { |  | 
|   300       execsql {EXPLAIN SELECT sum(a) FROM t2;} |  | 
|   301     } |  | 
|   302     execsql { |  | 
|   303       SELECT sum(a), count(a), avg(a), min(a), max(a), count(*) FROM t2; |  | 
|   304     } |  | 
|   305   } {68236 3 22745.0 1 67890 5} |  | 
|   306 } |  | 
|   307 do_test func-8.2 { |  | 
|   308   execsql { |  | 
|   309     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t2; |  | 
|   310   } |  | 
|   311 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} |  | 
|   312  |  | 
|   313 ifcapable tempdb { |  | 
|   314   do_test func-8.3 { |  | 
|   315     execsql { |  | 
|   316       CREATE TEMP TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; |  | 
|   317       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; |  | 
|   318     } |  | 
|   319   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} |  | 
|   320 } else { |  | 
|   321   do_test func-8.3 { |  | 
|   322     execsql { |  | 
|   323       CREATE TABLE t3 AS SELECT a FROM t2 ORDER BY a DESC; |  | 
|   324       SELECT min('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; |  | 
|   325     } |  | 
|   326   } {z+1abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} |  | 
|   327 } |  | 
|   328 do_test func-8.4 { |  | 
|   329   execsql { |  | 
|   330     SELECT max('z+'||a||'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP') FROM t3; |  | 
|   331   } |  | 
|   332 } {z+67890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP} |  | 
|   333 ifcapable compound { |  | 
|   334   do_test func-8.5 { |  | 
|   335     execsql { |  | 
|   336       SELECT sum(x) FROM (SELECT '9223372036' || '854775807' AS x |  | 
|   337                           UNION ALL SELECT -9223372036854775807) |  | 
|   338     } |  | 
|   339   } {0} |  | 
|   340   do_test func-8.6 { |  | 
|   341     execsql { |  | 
|   342       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775807' AS x |  | 
|   343                           UNION ALL SELECT -9223372036854775807) |  | 
|   344     } |  | 
|   345   } {integer} |  | 
|   346   do_test func-8.7 { |  | 
|   347     execsql { |  | 
|   348       SELECT typeof(sum(x)) FROM (SELECT '9223372036' || '854775808' AS x |  | 
|   349                           UNION ALL SELECT -9223372036854775807) |  | 
|   350     } |  | 
|   351   } {real} |  | 
|   352 ifcapable floatingpoint { |  | 
|   353   do_test func-8.8 { |  | 
|   354     execsql { |  | 
|   355       SELECT sum(x)>0.0 FROM (SELECT '9223372036' || '854775808' AS x |  | 
|   356                           UNION ALL SELECT -9223372036850000000) |  | 
|   357     } |  | 
|   358   } {1} |  | 
|   359 } |  | 
|   360 ifcapable !floatingpoint { |  | 
|   361   do_test func-8.8 { |  | 
|   362     execsql { |  | 
|   363       SELECT sum(x)>0 FROM (SELECT '9223372036' || '854775808' AS x |  | 
|   364                           UNION ALL SELECT -9223372036850000000) |  | 
|   365     } |  | 
|   366   } {1} |  | 
|   367 } |  | 
|   368 } |  | 
|   369  |  | 
|   370 # How do you test the random() function in a meaningful, deterministic way? |  | 
|   371 # |  | 
|   372 do_test func-9.1 { |  | 
|   373   execsql { |  | 
|   374     SELECT random() is not null; |  | 
|   375   } |  | 
|   376 } {1} |  | 
|   377 do_test func-9.2 { |  | 
|   378   execsql { |  | 
|   379     SELECT typeof(random()); |  | 
|   380   } |  | 
|   381 } {integer} |  | 
|   382 do_test func-9.3 { |  | 
|   383   execsql { |  | 
|   384     SELECT randomblob(32) is not null; |  | 
|   385   } |  | 
|   386 } {1} |  | 
|   387 do_test func-9.4 { |  | 
|   388   execsql { |  | 
|   389     SELECT typeof(randomblob(32)); |  | 
|   390   } |  | 
|   391 } {blob} |  | 
|   392 do_test func-9.5 { |  | 
|   393   execsql { |  | 
|   394     SELECT length(randomblob(32)), length(randomblob(-5)), |  | 
|   395            length(randomblob(2000)) |  | 
|   396   } |  | 
|   397 } {32 1 2000} |  | 
|   398  |  | 
|   399 # The "hex()" function was added in order to be able to render blobs |  | 
|   400 # generated by randomblob().  So this seems like a good place to test |  | 
|   401 # hex(). |  | 
|   402 # |  | 
|   403 ifcapable bloblit { |  | 
|   404   do_test func-9.10 { |  | 
|   405     execsql {SELECT hex(x'00112233445566778899aAbBcCdDeEfF')} |  | 
|   406   } {00112233445566778899AABBCCDDEEFF} |  | 
|   407 } |  | 
|   408 set encoding [db one {PRAGMA encoding}] |  | 
|   409 if {$encoding=="UTF-16le"} { |  | 
|   410   do_test func-9.11-utf16le { |  | 
|   411     execsql {SELECT hex(replace('abcdefg','ef','12'))} |  | 
|   412   } {6100620063006400310032006700} |  | 
|   413   do_test func-9.12-utf16le { |  | 
|   414     execsql {SELECT hex(replace('abcdefg','','12'))} |  | 
|   415   } {6100620063006400650066006700} |  | 
|   416   do_test func-9.13-utf16le { |  | 
|   417     execsql {SELECT hex(replace('aabcdefg','a','aaa'))} |  | 
|   418   } {610061006100610061006100620063006400650066006700} |  | 
|   419 } elseif {$encoding=="UTF-8"} { |  | 
|   420   do_test func-9.11-utf8 { |  | 
|   421     execsql {SELECT hex(replace('abcdefg','ef','12'))} |  | 
|   422   } {61626364313267} |  | 
|   423   do_test func-9.12-utf8 { |  | 
|   424     execsql {SELECT hex(replace('abcdefg','','12'))} |  | 
|   425   } {61626364656667} |  | 
|   426   do_test func-9.13-utf8 { |  | 
|   427     execsql {SELECT hex(replace('aabcdefg','a','aaa'))} |  | 
|   428   } {616161616161626364656667} |  | 
|   429 } |  | 
|   430    |  | 
|   431 # Use the "sqlite_register_test_function" TCL command which is part of |  | 
|   432 # the text fixture in order to verify correct operation of some of |  | 
|   433 # the user-defined SQL function APIs that are not used by the built-in |  | 
|   434 # functions. |  | 
|   435 # |  | 
|   436 set ::DB [sqlite3_connection_pointer db] |  | 
|   437 sqlite_register_test_function $::DB testfunc |  | 
|   438 do_test func-10.1 { |  | 
|   439   catchsql { |  | 
|   440     SELECT testfunc(NULL,NULL); |  | 
|   441   } |  | 
|   442 } {1 {first argument should be one of: int int64 string double null value}} |  | 
|   443 do_test func-10.2 { |  | 
|   444   execsql { |  | 
|   445     SELECT testfunc( |  | 
|   446      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   447      'int', 1234 |  | 
|   448     ); |  | 
|   449   } |  | 
|   450 } {1234} |  | 
|   451 do_test func-10.3 { |  | 
|   452   execsql { |  | 
|   453     SELECT testfunc( |  | 
|   454      'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   455      'string', NULL |  | 
|   456     ); |  | 
|   457   } |  | 
|   458 } {{}} |  | 
|   459  |  | 
|   460 ifcapable floatingpoint { |  | 
|   461   do_test func-10.4 { |  | 
|   462     execsql { |  | 
|   463       SELECT testfunc( |  | 
|   464        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   465        'double', 1.234 |  | 
|   466       ); |  | 
|   467     } |  | 
|   468   } {1.234} |  | 
|   469   do_test func-10.5 { |  | 
|   470     execsql { |  | 
|   471       SELECT testfunc( |  | 
|   472        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   473        'int', 1234, |  | 
|   474        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   475        'string', NULL, |  | 
|   476        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   477        'double', 1.234, |  | 
|   478        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   479        'int', 1234, |  | 
|   480        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   481        'string', NULL, |  | 
|   482        'string', 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', |  | 
|   483        'double', 1.234 |  | 
|   484       ); |  | 
|   485     } |  | 
|   486   } {1.234} |  | 
|   487 } |  | 
|   488  |  | 
|   489 # Test the built-in sqlite_version(*) SQL function. |  | 
|   490 # |  | 
|   491 do_test func-11.1 { |  | 
|   492   execsql { |  | 
|   493     SELECT sqlite_version(*); |  | 
|   494   } |  | 
|   495 } [sqlite3 -version] |  | 
|   496  |  | 
|   497 # Test that destructors passed to sqlite3 by calls to sqlite3_result_text() |  | 
|   498 # etc. are called. These tests use two special user-defined functions |  | 
|   499 # (implemented in func.c) only available in test builds.  |  | 
|   500 # |  | 
|   501 # Function test_destructor() takes one argument and returns a copy of the |  | 
|   502 # text form of that argument. A destructor is associated with the return |  | 
|   503 # value. Function test_destructor_count() returns the number of outstanding |  | 
|   504 # destructor calls for values returned by test_destructor(). |  | 
|   505 # |  | 
|   506 if {[db eval {PRAGMA encoding}]=="UTF-8"} { |  | 
|   507   do_test func-12.1-utf8 { |  | 
|   508     execsql { |  | 
|   509       SELECT test_destructor('hello world'), test_destructor_count(); |  | 
|   510     } |  | 
|   511   } {{hello world} 1} |  | 
|   512 } else { |  | 
|   513     ifcapable {utf16} { |  | 
|   514       do_test func-12.1-utf16 { |  | 
|   515         execsql { |  | 
|   516           SELECT test_destructor16('hello world'), test_destructor_count(); |  | 
|   517         } |  | 
|   518       } {{hello world} 1} |  | 
|   519     } |  | 
|   520 } |  | 
|   521 do_test func-12.2 { |  | 
|   522   execsql { |  | 
|   523     SELECT test_destructor_count(); |  | 
|   524   } |  | 
|   525 } {0} |  | 
|   526 do_test func-12.3 { |  | 
|   527   execsql { |  | 
|   528     SELECT test_destructor('hello')||' world' |  | 
|   529   } |  | 
|   530 } {{hello world}} |  | 
|   531 do_test func-12.4 { |  | 
|   532   execsql { |  | 
|   533     SELECT test_destructor_count(); |  | 
|   534   } |  | 
|   535 } {0} |  | 
|   536 do_test func-12.5 { |  | 
|   537   execsql { |  | 
|   538     CREATE TABLE t4(x); |  | 
|   539     INSERT INTO t4 VALUES(test_destructor('hello')); |  | 
|   540     INSERT INTO t4 VALUES(test_destructor('world')); |  | 
|   541     SELECT min(test_destructor(x)), max(test_destructor(x)) FROM t4; |  | 
|   542   } |  | 
|   543 } {hello world} |  | 
|   544 do_test func-12.6 { |  | 
|   545   execsql { |  | 
|   546     SELECT test_destructor_count(); |  | 
|   547   } |  | 
|   548 } {0} |  | 
|   549 do_test func-12.7 { |  | 
|   550   execsql { |  | 
|   551     DROP TABLE t4; |  | 
|   552   } |  | 
|   553 } {} |  | 
|   554  |  | 
|   555  |  | 
|   556 # Test that the auxdata API for scalar functions works. This test uses |  | 
|   557 # a special user-defined function only available in test builds, |  | 
|   558 # test_auxdata(). Function test_auxdata() takes any number of arguments. |  | 
|   559 do_test func-13.1 { |  | 
|   560   execsql { |  | 
|   561     SELECT test_auxdata('hello world'); |  | 
|   562   } |  | 
|   563 } {0} |  | 
|   564  |  | 
|   565 do_test func-13.2 { |  | 
|   566   execsql { |  | 
|   567     CREATE TABLE t4(a, b); |  | 
|   568     INSERT INTO t4 VALUES('abc', 'def'); |  | 
|   569     INSERT INTO t4 VALUES('ghi', 'jkl'); |  | 
|   570   } |  | 
|   571 } {} |  | 
|   572 do_test func-13.3 { |  | 
|   573   execsql { |  | 
|   574     SELECT test_auxdata('hello world') FROM t4; |  | 
|   575   } |  | 
|   576 } {0 1} |  | 
|   577 do_test func-13.4 { |  | 
|   578   execsql { |  | 
|   579     SELECT test_auxdata('hello world', 123) FROM t4; |  | 
|   580   } |  | 
|   581 } {{0 0} {1 1}} |  | 
|   582 do_test func-13.5 { |  | 
|   583   execsql { |  | 
|   584     SELECT test_auxdata('hello world', a) FROM t4; |  | 
|   585   } |  | 
|   586 } {{0 0} {1 0}} |  | 
|   587 do_test func-13.6 { |  | 
|   588   execsql { |  | 
|   589     SELECT test_auxdata('hello'||'world', a) FROM t4; |  | 
|   590   } |  | 
|   591 } {{0 0} {1 0}} |  | 
|   592  |  | 
|   593 # Test that auxilary data is preserved between calls for SQL variables. |  | 
|   594 do_test func-13.7 { |  | 
|   595   set DB [sqlite3_connection_pointer db] |  | 
|   596   set sql "SELECT test_auxdata( ? , a ) FROM t4;" |  | 
|   597   set STMT [sqlite3_prepare $DB $sql -1 TAIL] |  | 
|   598   sqlite3_bind_text $STMT 1 hello\000 -1 |  | 
|   599   set res [list] |  | 
|   600   while { "SQLITE_ROW"==[sqlite3_step $STMT] } { |  | 
|   601     lappend res [sqlite3_column_text $STMT 0] |  | 
|   602   } |  | 
|   603   lappend res [sqlite3_finalize $STMT] |  | 
|   604 } {{0 0} {1 0} SQLITE_OK} |  | 
|   605  |  | 
|   606 # Make sure that a function with a very long name is rejected |  | 
|   607 do_test func-14.1 { |  | 
|   608   catch { |  | 
|   609     db function [string repeat X 254] {return "hello"} |  | 
|   610   }  |  | 
|   611 } {0} |  | 
|   612 do_test func-14.2 { |  | 
|   613   catch { |  | 
|   614     db function [string repeat X 256] {return "hello"} |  | 
|   615   } |  | 
|   616 } {1} |  | 
|   617  |  | 
|   618 do_test func-15.1 { |  | 
|   619   catchsql {select test_error(NULL)} |  | 
|   620 } {1 {}} |  | 
|   621 do_test func-15.2 { |  | 
|   622   catchsql {select test_error('this is the error message')} |  | 
|   623 } {1 {this is the error message}} |  | 
|   624 do_test func-15.3 { |  | 
|   625   catchsql {select test_error('this is the error message',12)} |  | 
|   626 } {1 {this is the error message}} |  | 
|   627 do_test func-15.4 { |  | 
|   628   db errorcode |  | 
|   629 } {12} |  | 
|   630  |  | 
|   631 # Test the quote function for BLOB and NULL values. |  | 
|   632 do_test func-16.1 { |  | 
|   633   execsql { |  | 
|   634     CREATE TABLE tbl2(a, b); |  | 
|   635   } |  | 
|   636   set STMT [sqlite3_prepare $::DB "INSERT INTO tbl2 VALUES(?, ?)" -1 TAIL] |  | 
|   637   sqlite3_bind_blob $::STMT 1 abc 3 |  | 
|   638   sqlite3_step $::STMT |  | 
|   639   sqlite3_finalize $::STMT |  | 
|   640   execsql { |  | 
|   641     SELECT quote(a), quote(b) FROM tbl2; |  | 
|   642   } |  | 
|   643 } {X'616263' NULL} |  | 
|   644  |  | 
|   645 # Correctly handle function error messages that include %.  Ticket #1354 |  | 
|   646 # |  | 
|   647 do_test func-17.1 { |  | 
|   648   proc testfunc1 args {error "Error %d with %s percents %p"} |  | 
|   649   db function testfunc1 ::testfunc1 |  | 
|   650   catchsql { |  | 
|   651     SELECT testfunc1(1,2,3); |  | 
|   652   } |  | 
|   653 } {1 {Error %d with %s percents %p}} |  | 
|   654  |  | 
|   655 # The SUM function should return integer results when all inputs are integer. |  | 
|   656 # |  | 
|   657 do_test func-18.1 { |  | 
|   658   execsql { |  | 
|   659     CREATE TABLE t5(x); |  | 
|   660     INSERT INTO t5 VALUES(1); |  | 
|   661     INSERT INTO t5 VALUES(-99); |  | 
|   662     INSERT INTO t5 VALUES(10000); |  | 
|   663     SELECT sum(x) FROM t5; |  | 
|   664   } |  | 
|   665 } {9902} |  | 
|   666 ifcapable floatingpoint { |  | 
|   667   do_test func-18.2 { |  | 
|   668     execsql { |  | 
|   669       INSERT INTO t5 VALUES(0.0); |  | 
|   670       SELECT sum(x) FROM t5; |  | 
|   671     } |  | 
|   672   } {9902.0} |  | 
|   673 } |  | 
|   674  |  | 
|   675 # The sum of nothing is NULL.  But the sum of all NULLs is NULL. |  | 
|   676 # |  | 
|   677 # The TOTAL of nothing is 0.0. |  | 
|   678 # |  | 
|   679 do_test func-18.3 { |  | 
|   680   execsql { |  | 
|   681     DELETE FROM t5; |  | 
|   682     SELECT sum(x), total(x) FROM t5; |  | 
|   683   } |  | 
|   684 } {{} 0.0} |  | 
|   685 do_test func-18.4 { |  | 
|   686   execsql { |  | 
|   687     INSERT INTO t5 VALUES(NULL); |  | 
|   688     SELECT sum(x), total(x) FROM t5 |  | 
|   689   } |  | 
|   690 } {{} 0.0} |  | 
|   691 do_test func-18.5 { |  | 
|   692   execsql { |  | 
|   693     INSERT INTO t5 VALUES(NULL); |  | 
|   694     SELECT sum(x), total(x) FROM t5 |  | 
|   695   } |  | 
|   696 } {{} 0.0} |  | 
|   697 do_test func-18.6 { |  | 
|   698   execsql { |  | 
|   699     INSERT INTO t5 VALUES(123); |  | 
|   700     SELECT sum(x), total(x) FROM t5 |  | 
|   701   } |  | 
|   702 } {123 123.0} |  | 
|   703  |  | 
|   704 # Ticket #1664, #1669, #1670, #1674: An integer overflow on SUM causes |  | 
|   705 # an error. The non-standard TOTAL() function continues to give a helpful |  | 
|   706 # result. |  | 
|   707 # |  | 
|   708 do_test func-18.10 { |  | 
|   709   execsql { |  | 
|   710     CREATE TABLE t6(x INTEGER); |  | 
|   711     INSERT INTO t6 VALUES(1); |  | 
|   712     INSERT INTO t6 VALUES(1<<62); |  | 
|   713     SELECT sum(x) - ((1<<62)+1) from t6; |  | 
|   714   } |  | 
|   715 } 0 |  | 
|   716 do_test func-18.11 { |  | 
|   717   execsql { |  | 
|   718     SELECT typeof(sum(x)) FROM t6 |  | 
|   719   } |  | 
|   720 } integer |  | 
|   721 ifcapable floatingpoint { |  | 
|   722   do_test func-18.12 { |  | 
|   723     catchsql { |  | 
|   724       INSERT INTO t6 VALUES(1<<62); |  | 
|   725       SELECT sum(x) - ((1<<62)*2.0+1) from t6; |  | 
|   726     } |  | 
|   727   } {1 {integer overflow}} |  | 
|   728   do_test func-18.13 { |  | 
|   729     execsql { |  | 
|   730       SELECT total(x) - ((1<<62)*2.0+1) FROM t6 |  | 
|   731     } |  | 
|   732   } 0.0 |  | 
|   733 } |  | 
|   734 ifcapable !floatingpoint { |  | 
|   735   do_test func-18.12 { |  | 
|   736     catchsql { |  | 
|   737       INSERT INTO t6 VALUES(1<<62); |  | 
|   738       SELECT sum(x) - ((1<<62)*2+1) from t6; |  | 
|   739     } |  | 
|   740   } {1 {integer overflow}} |  | 
|   741   do_test func-18.13 { |  | 
|   742     execsql { |  | 
|   743       SELECT total(x) - ((1<<62)*2+1) FROM t6 |  | 
|   744     } |  | 
|   745   } 0.0 |  | 
|   746 } |  | 
|   747 if {[working_64bit_int]} { |  | 
|   748   do_test func-18.14 { |  | 
|   749     execsql { |  | 
|   750       SELECT sum(-9223372036854775805); |  | 
|   751     } |  | 
|   752   } -9223372036854775805 |  | 
|   753 } |  | 
|   754 ifcapable compound&&subquery { |  | 
|   755  |  | 
|   756 do_test func-18.15 { |  | 
|   757   catchsql { |  | 
|   758     SELECT sum(x) FROM  |  | 
|   759        (SELECT 9223372036854775807 AS x UNION ALL |  | 
|   760         SELECT 10 AS x); |  | 
|   761   } |  | 
|   762 } {1 {integer overflow}} |  | 
|   763 if {[working_64bit_int]} { |  | 
|   764   do_test func-18.16 { |  | 
|   765     catchsql { |  | 
|   766       SELECT sum(x) FROM  |  | 
|   767          (SELECT 9223372036854775807 AS x UNION ALL |  | 
|   768           SELECT -10 AS x); |  | 
|   769     } |  | 
|   770   } {0 9223372036854775797} |  | 
|   771   do_test func-18.17 { |  | 
|   772     catchsql { |  | 
|   773       SELECT sum(x) FROM  |  | 
|   774          (SELECT -9223372036854775807 AS x UNION ALL |  | 
|   775           SELECT 10 AS x); |  | 
|   776     } |  | 
|   777   } {0 -9223372036854775797} |  | 
|   778 } |  | 
|   779 do_test func-18.18 { |  | 
|   780   catchsql { |  | 
|   781     SELECT sum(x) FROM  |  | 
|   782        (SELECT -9223372036854775807 AS x UNION ALL |  | 
|   783         SELECT -10 AS x); |  | 
|   784   } |  | 
|   785 } {1 {integer overflow}} |  | 
|   786 do_test func-18.19 { |  | 
|   787   catchsql { |  | 
|   788     SELECT sum(x) FROM (SELECT 9 AS x UNION ALL SELECT -10 AS x); |  | 
|   789   } |  | 
|   790 } {0 -1} |  | 
|   791 do_test func-18.20 { |  | 
|   792   catchsql { |  | 
|   793     SELECT sum(x) FROM (SELECT -9 AS x UNION ALL SELECT 10 AS x); |  | 
|   794   } |  | 
|   795 } {0 1} |  | 
|   796 do_test func-18.21 { |  | 
|   797   catchsql { |  | 
|   798     SELECT sum(x) FROM (SELECT -10 AS x UNION ALL SELECT 9 AS x); |  | 
|   799   } |  | 
|   800 } {0 -1} |  | 
|   801 do_test func-18.22 { |  | 
|   802   catchsql { |  | 
|   803     SELECT sum(x) FROM (SELECT 10 AS x UNION ALL SELECT -9 AS x); |  | 
|   804   } |  | 
|   805 } {0 1} |  | 
|   806  |  | 
|   807 } ;# ifcapable compound&&subquery |  | 
|   808  |  | 
|   809 # Integer overflow on abs() |  | 
|   810 # |  | 
|   811 if {[working_64bit_int]} { |  | 
|   812   do_test func-18.31 { |  | 
|   813     catchsql { |  | 
|   814       SELECT abs(-9223372036854775807); |  | 
|   815     } |  | 
|   816   } {0 9223372036854775807} |  | 
|   817 } |  | 
|   818 do_test func-18.32 { |  | 
|   819   catchsql { |  | 
|   820     SELECT abs(-9223372036854775807-1); |  | 
|   821   } |  | 
|   822 } {1 {integer overflow}} |  | 
|   823  |  | 
|   824 # The MATCH function exists but is only a stub and always throws an error. |  | 
|   825 # |  | 
|   826 do_test func-19.1 { |  | 
|   827   execsql { |  | 
|   828     SELECT match(a,b) FROM t1 WHERE 0; |  | 
|   829   } |  | 
|   830 } {} |  | 
|   831 do_test func-19.2 { |  | 
|   832   catchsql { |  | 
|   833     SELECT 'abc' MATCH 'xyz'; |  | 
|   834   } |  | 
|   835 } {1 {unable to use function MATCH in the requested context}} |  | 
|   836 do_test func-19.3 { |  | 
|   837   catchsql { |  | 
|   838     SELECT 'abc' NOT MATCH 'xyz'; |  | 
|   839   } |  | 
|   840 } {1 {unable to use function MATCH in the requested context}} |  | 
|   841 do_test func-19.4 { |  | 
|   842   catchsql { |  | 
|   843     SELECT match(1,2,3); |  | 
|   844   } |  | 
|   845 } {1 {wrong number of arguments to function match()}} |  | 
|   846  |  | 
|   847 # Soundex tests. |  | 
|   848 # |  | 
|   849 if {![catch {db eval {SELECT soundex('hello')}}]} { |  | 
|   850   set i 0 |  | 
|   851   foreach {name sdx} { |  | 
|   852     euler        E460 |  | 
|   853     EULER        E460 |  | 
|   854     Euler        E460 |  | 
|   855     ellery       E460 |  | 
|   856     gauss        G200 |  | 
|   857     ghosh        G200 |  | 
|   858     hilbert      H416 |  | 
|   859     Heilbronn    H416 |  | 
|   860     knuth        K530 |  | 
|   861     kant         K530 |  | 
|   862     Lloyd        L300 |  | 
|   863     LADD         L300 |  | 
|   864     Lukasiewicz  L222 |  | 
|   865     Lissajous    L222 |  | 
|   866     A            A000 |  | 
|   867     12345        ?000 |  | 
|   868   } { |  | 
|   869     incr i |  | 
|   870     do_test func-20.$i { |  | 
|   871       execsql {SELECT soundex($name)} |  | 
|   872     } $sdx |  | 
|   873   } |  | 
|   874 } |  | 
|   875  |  | 
|   876 # Tests of the REPLACE function. |  | 
|   877 # |  | 
|   878 do_test func-21.1 { |  | 
|   879   catchsql { |  | 
|   880     SELECT replace(1,2); |  | 
|   881   } |  | 
|   882 } {1 {wrong number of arguments to function replace()}} |  | 
|   883 do_test func-21.2 { |  | 
|   884   catchsql { |  | 
|   885     SELECT replace(1,2,3,4); |  | 
|   886   } |  | 
|   887 } {1 {wrong number of arguments to function replace()}} |  | 
|   888 do_test func-21.3 { |  | 
|   889   execsql { |  | 
|   890     SELECT typeof(replace("This is the main test string", NULL, "ALT")); |  | 
|   891   } |  | 
|   892 } {null} |  | 
|   893 do_test func-21.4 { |  | 
|   894   execsql { |  | 
|   895     SELECT typeof(replace(NULL, "main", "ALT")); |  | 
|   896   } |  | 
|   897 } {null} |  | 
|   898 do_test func-21.5 { |  | 
|   899   execsql { |  | 
|   900     SELECT typeof(replace("This is the main test string", "main", NULL)); |  | 
|   901   } |  | 
|   902 } {null} |  | 
|   903 do_test func-21.6 { |  | 
|   904   execsql { |  | 
|   905     SELECT replace("This is the main test string", "main", "ALT"); |  | 
|   906   } |  | 
|   907 } {{This is the ALT test string}} |  | 
|   908 do_test func-21.7 { |  | 
|   909   execsql { |  | 
|   910     SELECT replace("This is the main test string", "main", "larger-main"); |  | 
|   911   } |  | 
|   912 } {{This is the larger-main test string}} |  | 
|   913 do_test func-21.8 { |  | 
|   914   execsql { |  | 
|   915     SELECT replace("aaaaaaa", "a", "0123456789"); |  | 
|   916   } |  | 
|   917 } {0123456789012345678901234567890123456789012345678901234567890123456789} |  | 
|   918  |  | 
|   919 ifcapable tclvar { |  | 
|   920   do_test func-21.9 { |  | 
|   921     # Attempt to exploit a buffer-overflow that at one time existed  |  | 
|   922     # in the REPLACE function.  |  | 
|   923     set ::str "[string repeat A 29998]CC[string repeat A 35537]" |  | 
|   924     set ::rep [string repeat B 65536] |  | 
|   925     execsql { |  | 
|   926       SELECT LENGTH(REPLACE($::str, 'C', $::rep)); |  | 
|   927     } |  | 
|   928   } [expr 29998 + 2*65536 + 35537] |  | 
|   929 } |  | 
|   930  |  | 
|   931 # Tests for the TRIM, LTRIM and RTRIM functions. |  | 
|   932 # |  | 
|   933 do_test func-22.1 { |  | 
|   934   catchsql {SELECT trim(1,2,3)} |  | 
|   935 } {1 {wrong number of arguments to function trim()}} |  | 
|   936 do_test func-22.2 { |  | 
|   937   catchsql {SELECT ltrim(1,2,3)} |  | 
|   938 } {1 {wrong number of arguments to function ltrim()}} |  | 
|   939 do_test func-22.3 { |  | 
|   940   catchsql {SELECT rtrim(1,2,3)} |  | 
|   941 } {1 {wrong number of arguments to function rtrim()}} |  | 
|   942 do_test func-22.4 { |  | 
|   943   execsql {SELECT trim('  hi  ');} |  | 
|   944 } {hi} |  | 
|   945 do_test func-22.5 { |  | 
|   946   execsql {SELECT ltrim('  hi  ');} |  | 
|   947 } {{hi  }} |  | 
|   948 do_test func-22.6 { |  | 
|   949   execsql {SELECT rtrim('  hi  ');} |  | 
|   950 } {{  hi}} |  | 
|   951 do_test func-22.7 { |  | 
|   952   execsql {SELECT trim('  hi  ','xyz');} |  | 
|   953 } {{  hi  }} |  | 
|   954 do_test func-22.8 { |  | 
|   955   execsql {SELECT ltrim('  hi  ','xyz');} |  | 
|   956 } {{  hi  }} |  | 
|   957 do_test func-22.9 { |  | 
|   958   execsql {SELECT rtrim('  hi  ','xyz');} |  | 
|   959 } {{  hi  }} |  | 
|   960 do_test func-22.10 { |  | 
|   961   execsql {SELECT trim('xyxzy  hi  zzzy','xyz');} |  | 
|   962 } {{  hi  }} |  | 
|   963 do_test func-22.11 { |  | 
|   964   execsql {SELECT ltrim('xyxzy  hi  zzzy','xyz');} |  | 
|   965 } {{  hi  zzzy}} |  | 
|   966 do_test func-22.12 { |  | 
|   967   execsql {SELECT rtrim('xyxzy  hi  zzzy','xyz');} |  | 
|   968 } {{xyxzy  hi  }} |  | 
|   969 do_test func-22.13 { |  | 
|   970   execsql {SELECT trim('  hi  ','');} |  | 
|   971 } {{  hi  }} |  | 
|   972 if {[db one {PRAGMA encoding}]=="UTF-8"} { |  | 
|   973   do_test func-22.14 { |  | 
|   974     execsql {SELECT hex(trim(x'c280e1bfbff48fbfbf6869',x'6162e1bfbfc280'))} |  | 
|   975   } {F48FBFBF6869} |  | 
|   976   do_test func-22.15 { |  | 
|   977     execsql {SELECT hex(trim(x'6869c280e1bfbff48fbfbf61', |  | 
|   978                              x'6162e1bfbfc280f48fbfbf'))} |  | 
|   979   } {6869} |  | 
|   980   do_test func-22.16 { |  | 
|   981     execsql {SELECT hex(trim(x'ceb1ceb2ceb3',x'ceb1'));} |  | 
|   982   } {CEB2CEB3} |  | 
|   983 } |  | 
|   984 do_test func-22.20 { |  | 
|   985   execsql {SELECT typeof(trim(NULL));} |  | 
|   986 } {null} |  | 
|   987 do_test func-22.21 { |  | 
|   988   execsql {SELECT typeof(trim(NULL,'xyz'));} |  | 
|   989 } {null} |  | 
|   990 do_test func-22.22 { |  | 
|   991   execsql {SELECT typeof(trim('hello',NULL));} |  | 
|   992 } {null} |  | 
|   993  |  | 
|   994 # This is to test the deprecated sqlite3_aggregate_count() API. |  | 
|   995 # |  | 
|   996 ifcapable deprecated { |  | 
|   997   do_test func-23.1 { |  | 
|   998     sqlite3_create_aggregate db |  | 
|   999     execsql { |  | 
|  1000       SELECT legacy_count() FROM t6; |  | 
|  1001     } |  | 
|  1002   } {3} |  | 
|  1003 } |  | 
|  1004  |  | 
|  1005 # The group_concat() function. |  | 
|  1006 # |  | 
|  1007 do_test func-24.1 { |  | 
|  1008   execsql { |  | 
|  1009     SELECT group_concat(t1) FROM tbl1 |  | 
|  1010   } |  | 
|  1011 } {this,program,is,free,software} |  | 
|  1012 do_test func-24.2 { |  | 
|  1013   execsql { |  | 
|  1014     SELECT group_concat(t1,' ') FROM tbl1 |  | 
|  1015   } |  | 
|  1016 } {{this program is free software}} |  | 
|  1017 do_test func-24.3 { |  | 
|  1018   execsql { |  | 
|  1019     SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1 |  | 
|  1020   } |  | 
|  1021 } {{this 2 program 3 is 4 free 5 software}} |  | 
|  1022 do_test func-24.4 { |  | 
|  1023   execsql { |  | 
|  1024     SELECT group_concat(NULL,t1) FROM tbl1 |  | 
|  1025   } |  | 
|  1026 } {{}} |  | 
|  1027 do_test func-24.5 { |  | 
|  1028   execsql { |  | 
|  1029     SELECT group_concat(t1,NULL) FROM tbl1 |  | 
|  1030   } |  | 
|  1031 } {thisprogramisfreesoftware} |  | 
|  1032 do_test func-24.6 { |  | 
|  1033   execsql { |  | 
|  1034     SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 |  | 
|  1035   } |  | 
|  1036 } {BEGIN-this,program,is,free,software} |  | 
|  1037  |  | 
|  1038 # Ticket #3179:  Make sure aggregate functions can take many arguments. |  | 
|  1039 # None of the built-in aggregates do this, so use the md5sum() from the |  | 
|  1040 # test extensions. |  | 
|  1041 # |  | 
|  1042 unset -nocomplain midargs |  | 
|  1043 set midargs {} |  | 
|  1044 unset -nocomplain midres |  | 
|  1045 set midres {} |  | 
|  1046 unset -nocomplain result |  | 
|  1047 for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]} {incr i} { |  | 
|  1048   append midargs ,'/$i' |  | 
|  1049   append midres /$i |  | 
|  1050   set result [md5 \ |  | 
|  1051      "this${midres}program${midres}is${midres}free${midres}software${midres}"] |  | 
|  1052   set sql "SELECT md5sum(t1$midargs) FROM tbl1" |  | 
|  1053   do_test func-24.7.$i { |  | 
|  1054      db eval $::sql |  | 
|  1055   } $result |  | 
|  1056 } |  | 
|  1057  |  | 
|  1058 # Ticket #3806.  If the initial string in a group_concat is an empty |  | 
|  1059 # string, the separator that follows should still be present. |  | 
|  1060 # |  | 
|  1061 do_test func-24.8 { |  | 
|  1062   execsql { |  | 
|  1063     SELECT group_concat(CASE t1 WHEN 'this' THEN '' ELSE t1 END) FROM tbl1 |  | 
|  1064   } |  | 
|  1065 } {,program,is,free,software} |  | 
|  1066 do_test func-24.9 { |  | 
|  1067   execsql { |  | 
|  1068     SELECT group_concat(CASE WHEN t1!='software' THEN '' ELSE t1 END) FROM tbl1 |  | 
|  1069   } |  | 
|  1070 } {,,,,software} |  | 
|  1071  |  | 
|  1072 # Ticket #3923.  Initial empty strings have a separator.  But initial |  | 
|  1073 # NULLs do not. |  | 
|  1074 # |  | 
|  1075 do_test func-24.10 { |  | 
|  1076   execsql { |  | 
|  1077     SELECT group_concat(CASE t1 WHEN 'this' THEN null ELSE t1 END) FROM tbl1 |  | 
|  1078   } |  | 
|  1079 } {program,is,free,software} |  | 
|  1080 do_test func-24.11 { |  | 
|  1081   execsql { |  | 
|  1082    SELECT group_concat(CASE WHEN t1!='software' THEN null ELSE t1 END) FROM tbl1 |  | 
|  1083   } |  | 
|  1084 } {software} |  | 
|  1085 do_test func-24.12 { |  | 
|  1086   execsql { |  | 
|  1087     SELECT group_concat(CASE t1 WHEN 'this' THEN '' |  | 
|  1088                           WHEN 'program' THEN null ELSE t1 END) FROM tbl1 |  | 
|  1089   } |  | 
|  1090 } {,is,free,software} |  | 
|  1091  |  | 
|  1092  |  | 
|  1093 # Use the test_isolation function to make sure that type conversions |  | 
|  1094 # on function arguments do not effect subsequent arguments. |  | 
|  1095 # |  | 
|  1096 do_test func-25.1 { |  | 
|  1097   execsql {SELECT test_isolation(t1,t1) FROM tbl1} |  | 
|  1098 } {this program is free software} |  | 
|  1099  |  | 
|  1100 # Try to misuse the sqlite3_create_function() interface.  Verify that |  | 
|  1101 # errors are returned. |  | 
|  1102 # |  | 
|  1103 do_test func-26.1 { |  | 
|  1104   abuse_create_function db |  | 
|  1105 } {} |  | 
|  1106  |  | 
|  1107 # The previous test (func-26.1) registered a function with a very long |  | 
|  1108 # function name that takes many arguments and always returns NULL.  Verify |  | 
|  1109 # that this function works correctly. |  | 
|  1110 # |  | 
|  1111 do_test func-26.2 { |  | 
|  1112   set a {} |  | 
|  1113   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG} {incr i} { |  | 
|  1114     lappend a $i |  | 
|  1115   } |  | 
|  1116   db eval " |  | 
|  1117      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789([join $a ,]); |  | 
|  1118   " |  | 
|  1119 } {{}} |  | 
|  1120 do_test func-26.3 { |  | 
|  1121   set a {} |  | 
|  1122   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG+1} {incr i} { |  | 
|  1123     lappend a $i |  | 
|  1124   } |  | 
|  1125   catchsql " |  | 
|  1126      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789([join $a ,]); |  | 
|  1127   " |  | 
|  1128 } {1 {too many arguments on function nullx_123456789_123456789_123456789_1234567
      89_123456789_123456789_123456789_123456789_123456789_123456789_123456789_1234567
      89_123456789_123456789_123456789_123456789_123456789_123456789_123456789_1234567
      89_123456789_123456789_123456789_123456789_123456789}} |  | 
|  1129 do_test func-26.4 { |  | 
|  1130   set a {} |  | 
|  1131   for {set i 1} {$i<=$::SQLITE_MAX_FUNCTION_ARG-1} {incr i} { |  | 
|  1132     lappend a $i |  | 
|  1133   } |  | 
|  1134   catchsql " |  | 
|  1135      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789([join $a ,]); |  | 
|  1136   " |  | 
|  1137 } {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()}} |  | 
|  1138 do_test func-26.5 { |  | 
|  1139   catchsql " |  | 
|  1140      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_12345678a(0); |  | 
|  1141   " |  | 
|  1142 } {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}} |  | 
|  1143 do_test func-26.6 { |  | 
|  1144   catchsql " |  | 
|  1145      SELECT nullx_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789_12
      3456789_123456789_123456789a(0); |  | 
|  1146   " |  | 
|  1147 } {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}} |  | 
|  1148  |  | 
|  1149 do_test func-27.1 { |  | 
|  1150   catchsql {SELECT coalesce()} |  | 
|  1151 } {1 {wrong number of arguments to function coalesce()}} |  | 
|  1152 do_test func-27.2 { |  | 
|  1153   catchsql {SELECT coalesce(1)} |  | 
|  1154 } {1 {wrong number of arguments to function coalesce()}} |  | 
|  1155 do_test func-27.3 { |  | 
|  1156   catchsql {SELECT coalesce(1,2)} |  | 
|  1157 } {0 1} |  | 
|  1158  |  | 
|  1159 # Ticket 2d401a94287b5 |  | 
|  1160 # Unknown function in a DEFAULT expression causes a segfault. |  | 
|  1161 # |  | 
|  1162 do_test func-28.1 { |  | 
|  1163   db eval { |  | 
|  1164     CREATE TABLE t28(x, y DEFAULT(nosuchfunc(1))); |  | 
|  1165   } |  | 
|  1166   catchsql { |  | 
|  1167     INSERT INTO t28(x) VALUES(1); |  | 
|  1168   } |  | 
|  1169 } {1 {unknown function: nosuchfunc()}} |  | 
|  1170  |  | 
|  1171 finish_test |  | 
| OLD | NEW |