15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2008 March 19
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code for testing all sorts of SQLite interfaces.  This code
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** implements new SQL functions used by the test scripts.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqlite3.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tcl.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Allocate nByte bytes of space using sqlite3_malloc(). If the
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allocation fails, call sqlite3_result_error_nomem() to notify
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the database handle that malloc() has failed.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *testContextMalloc(sqlite3_context *context, int nByte){
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *z = sqlite3_malloc(nByte);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !z && nByte>0 ){
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error_nomem(context);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return z;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function generates a string of random characters.  Used for
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** generating test data.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const unsigned char zSrc[] =
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "abcdefghijklmnopqrstuvwxyz"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     "0123456789"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     ".-!,:*^+=_|?/<> ";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iMin, iMax, n, r, i;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char zBuf[1000];
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* It used to be possible to call randstr() with any number of arguments,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** but now it is registered with SQLite as requiring exactly 2.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(argc==2);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iMin = sqlite3_value_int(argv[0]);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( iMin<0 ) iMin = 0;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iMax = sqlite3_value_int(argv[1]);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( iMax<iMin ) iMax = iMin;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  n = iMin;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( iMax>iMin ){
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_randomness(sizeof(r), &r);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    r &= 0x7fffffff;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n += r%(iMax + 1 - iMin);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( n<sizeof(zBuf) );
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_randomness(n, zBuf);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<n; i++){
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zBuf[n] = 0;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following two SQL functions are used to test returning a text
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** result with a destructor. Function 'test_destructor' takes one argument
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and returns the same argument interpreted as TEXT. A destructor is
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** passed with the sqlite3_result_text() call.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQL function 'test_destructor_count' returns the number of outstanding
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allocations made by 'test_destructor';
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** WARNING: Not threadsafe.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_destructor_count_var = 0;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void destructor(void *p){
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zVal = (char *)p;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(zVal);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal--;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_free(zVal);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_destructor_count_var--;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_destructor(
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zVal;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int len;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_destructor_count_var++;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( nArg==1 );
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  len = sqlite3_value_bytes(argv[0]);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal = testContextMalloc(pCtx, len+3);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !zVal ){
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal[len+1] = 0;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal[len+2] = 0;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal++;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(zVal, sqlite3_value_text(argv[0]), len);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_text(pCtx, zVal, -1, destructor);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_destructor16(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zVal;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int len;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_destructor_count_var++;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( nArg==1 );
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  len = sqlite3_value_bytes16(argv[0]);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal = testContextMalloc(pCtx, len+3);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !zVal ){
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal[len+1] = 0;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal[len+2] = 0;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zVal++;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(zVal, sqlite3_value_text16(argv[0]), len);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_text16(pCtx, zVal, -1, destructor);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_destructor_count(
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_int(pCtx, test_destructor_count_var);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following aggregate function, test_agg_errmsg16(), takes zero
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** arguments. It returns the text value returned by the sqlite3_errmsg16()
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** API function.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_BUILTIN_TEST
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3BeginBenignMalloc(void);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3EndBenignMalloc(void);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #define sqlite3BeginBenignMalloc()
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #define sqlite3EndBenignMalloc()
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_agg_errmsg16_step(sqlite3_context *a, int b,sqlite3_value **c){
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_agg_errmsg16_final(sqlite3_context *ctx){
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void *z;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 * db = sqlite3_context_db_handle(ctx);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_aggregate_context(ctx, 2048);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3BeginBenignMalloc();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  z = sqlite3_errmsg16(db);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3EndBenignMalloc();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_text16(ctx, z, -1, SQLITE_TRANSIENT);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata()
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** interface.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The test_auxdata() SQL function attempts to register each of its arguments
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** as auxiliary data.  If there are no prior registrations of aux data for
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** that argument (meaning the argument is not a constant or this is its first
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** call) then the result for that argument is 0.  If there is a prior
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** registration, the result for that argument is 1.  The overall result
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is the individual argument results separated by spaces.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void free_test_auxdata(void *p) {sqlite3_free(p);}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_auxdata(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zRet = testContextMalloc(pCtx, nArg*2);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !zRet ) return;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(zRet, 0, nArg*2);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<nArg; i++){
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char const *z = (char*)sqlite3_value_text(argv[i]);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( z ){
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int n;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      char *zAux = sqlite3_get_auxdata(pCtx, i);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( zAux ){
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zRet[i*2] = '1';
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        assert( strcmp(zAux,z)==0 );
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }else {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zRet[i*2] = '0';
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      n = strlen(z) + 1;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zAux = testContextMalloc(pCtx, n);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( zAux ){
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memcpy(zAux, z, n);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zRet[i*2+1] = ' ';
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A function to test error reporting from user functions. This function
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** returns a copy of its first argument as the error message.  If the
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** second argument exists, it becomes the error code.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_error(
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), -1);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( nArg==2 ){
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error_code(pCtx, sqlite3_value_int(argv[1]));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Implementation of the counter(X) function.  If X is an integer
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** constant, then the first invocation will return X.  The second X+1.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and so forth.  Can be used (for example) to provide a sequence number
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in a result set.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void counterFunc(
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,   /* Function context */
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,                /* Number of function arguments */
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv     /* Values for all function arguments */
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int *pCounter = (int*)sqlite3_get_auxdata(pCtx, 0);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pCounter==0 ){
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pCounter = sqlite3_malloc( sizeof(*pCounter) );
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pCounter==0 ){
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3_result_error_nomem(pCtx);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *pCounter = sqlite3_value_int(argv[0]);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_set_auxdata(pCtx, 0, pCounter, sqlite3_free);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++*pCounter;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_int(pCtx, *pCounter);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function takes two arguments.  It performance UTF-8/16 type
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** conversions on the first argument then returns a copy of the second
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** argument.
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This function is used in cases such as the following:
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      SELECT test_isolation(x,x) FROM t1;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** We want to verify that the type conversions that occur on the
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** first argument do not invalidate the second argument.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_isolation(
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value_text16(argv[0]);
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value_text(argv[0]);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value_text16(argv[0]);
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value_text(argv[0]);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_value(pCtx, argv[1]);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Invoke an SQL statement recursively.  The function result is the
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** first column of the first row of the result set.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void test_eval(
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_stmt *pStmt;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = sqlite3_context_db_handle(pCtx);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zSql;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zSql = (char*)sqlite3_value_text(argv[0]);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_step(pStmt);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( rc==SQLITE_ROW ){
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3_result_value(pCtx, sqlite3_column_value(pStmt, 0));
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_finalize(pStmt);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ){
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zErr;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( pStmt==0 );
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zErr = sqlite3_mprintf("sqlite3_prepare_v2() error: %s",sqlite3_errmsg(db));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_text(pCtx, zErr, -1, sqlite3_free);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error_code(pCtx, rc);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** convert one character from hex to binary
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int testHexChar(char c){
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( c>='0' && c<='9' ){
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return c - '0';
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( c>='a' && c<='f' ){
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return c - 'a' + 10;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( c>='A' && c<='F' ){
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return c - 'A' + 10;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert hex to binary.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testHexToBin(const char *zIn, char *zOut){
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while( zIn[0] && zIn[1] ){
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *(zOut++) = (testHexChar(zIn[0])<<4) + testHexChar(zIn[1]);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zIn += 2;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      hex_to_utf16be(HEX)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert the input string from HEX into binary.  Then return the
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** result using sqlite3_result_text16le().
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testHexToUtf16be(
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zIn;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zOut;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( nArg==1 );
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  n = sqlite3_value_bytes(argv[0]);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zIn = (const char*)sqlite3_value_text(argv[0]);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zOut = sqlite3_malloc( n/2 );
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zOut==0 ){
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error_nomem(pCtx);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testHexToBin(zIn, zOut);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_text16be(pCtx, zOut, n/2, sqlite3_free);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      hex_to_utf8(HEX)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert the input string from HEX into binary.  Then return the
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** result using sqlite3_result_text16le().
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testHexToUtf8(
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zIn;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zOut;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( nArg==1 );
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  n = sqlite3_value_bytes(argv[0]);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zIn = (const char*)sqlite3_value_text(argv[0]);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zOut = sqlite3_malloc( n/2 );
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zOut==0 ){
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error_nomem(pCtx);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testHexToBin(zIn, zOut);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_text(pCtx, zOut, n/2, sqlite3_free);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**      hex_to_utf16le(HEX)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Convert the input string from HEX into binary.  Then return the
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** result using sqlite3_result_text16le().
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void testHexToUtf16le(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *pCtx,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nArg,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zIn;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zOut;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( nArg==1 );
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  n = sqlite3_value_bytes(argv[0]);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zIn = (const char*)sqlite3_value_text(argv[0]);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zOut = sqlite3_malloc( n/2 );
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zOut==0 ){
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error_nomem(pCtx);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testHexToBin(zIn, zOut);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_text16le(pCtx, zOut, n/2, sqlite3_free);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int registerTestFunctions(sqlite3 *db){
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const struct {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     char *zName;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     signed char nArg;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     unsigned char eTextRep; /* 1: UTF-16.  0: UTF-8 */
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aFuncs[] = {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "randstr",               2, SQLITE_UTF8, randStr    },
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_destructor",       1, SQLITE_UTF8, test_destructor},
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_UTF16
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_destructor16",     1, SQLITE_UTF8, test_destructor16},
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "hex_to_utf16be",        1, SQLITE_UTF8, testHexToUtf16be},
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "hex_to_utf16le",        1, SQLITE_UTF8, testHexToUtf16le},
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "hex_to_utf8",           1, SQLITE_UTF8, testHexToUtf8},
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count},
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_auxdata",         -1, SQLITE_UTF8, test_auxdata},
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_error",            1, SQLITE_UTF8, test_error},
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_error",            2, SQLITE_UTF8, test_error},
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_eval",             1, SQLITE_UTF8, test_eval},
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_isolation",        2, SQLITE_UTF8, test_isolation},
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "test_counter",          1, SQLITE_UTF8, counterFunc},
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_create_function(db, "test_agg_errmsg16", 0, SQLITE_ANY, 0, 0,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_agg_errmsg16_step, test_agg_errmsg16_final);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLITE_OK;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** TCLCMD:  autoinstall_test_functions
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Invoke this TCL command to use sqlite3_auto_extension() to cause
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the standard set of test functions to be loaded into each new
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** database connection.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int autoinstall_test_funcs(
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int Md5_Register(sqlite3*);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = sqlite3_auto_extension((void*)registerTestFunctions);
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3_auto_extension((void*)Md5_Register);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A bogus step function and finalizer function.
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void tStep(sqlite3_context *a, int b, sqlite3_value **c){}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void tFinal(sqlite3_context *a){}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** tclcmd:  abuse_create_function
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Make various calls to sqlite3_create_function that do not have valid
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** parameters.  Verify that the error condition is detected and reported.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int abuse_create_function(
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void * clientData,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int objc,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Obj *CONST objv[]
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int mxArg;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep,tStep,tFinal);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, tStep, 0);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, 0, tFinal);
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE) goto abuse_err;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, 0, 0, tFinal);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, 0, tStep, 0);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, 0, 0);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "tx", 128, SQLITE_UTF8, 0, tStep, 0, 0);
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "funcxx"
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789",
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       1, SQLITE_UTF8, 0, tStep, 0, 0);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_MISUSE ) goto abuse_err;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* This last function registration should actually work.  Generate
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** a no-op function (that always returns NULL) and which has the
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** maximum-length function name and the maximum number of parameters.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 10000);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mxArg = sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, -1);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_create_function(db, "nullx"
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789"
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       "_123456789_123456789_123456789_123456789_123456789",
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       mxArg, SQLITE_UTF8, 0, tStep, 0, 0);
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ) goto abuse_err;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)abuse_err:
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, "sqlite3_create_function abused test failed",
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   (char*)0);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_ERROR;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter.
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest_func_Init(Tcl_Interp *interp){
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     char *zName;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     Tcl_ObjCmdProc *xProc;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aObjCmd[] = {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "autoinstall_test_functions",    autoinstall_test_funcs },
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     { "abuse_create_function",         abuse_create_function  },
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int Md5_Register(sqlite3*);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_initialize();
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_auto_extension((void*)registerTestFunctions);
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_auto_extension((void*)Md5_Register);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
584