gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/func.test (about)

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