Team Ai
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 10mo agoView on Hugging Face
0likes
test1.c9431 linesDownload Raw Back to src
1/*2** 2001 September 153**4** The author disclaims copyright to this source code.  In place of5** a legal notice, here is a blessing:6**7**    May you do good and not evil.8**    May you find forgiveness for yourself and forgive others.9**    May you share freely, never taking more than you give.10**11*************************************************************************12** Code for testing all sorts of SQLite interfaces.  This code13** is not included in the SQLite library.  It is used for automated14** testing of the SQLite library.15*/16#include "sqliteInt.h"17#if SQLITE_OS_WIN18#  include "os_win.h"19#  include <windows.h>20#else21#  include <unistd.h>22#  if defined(__APPLE__)23#    include <sys/param.h>24#    include <sys/sysctl.h>25#  endif26#endif27 28#include "vdbeInt.h"29#include "tclsqlite.h"30#include <stdlib.h>31#include <string.h>32 33/*34** This is a copy of the first part of the SqliteDb structure in 35** tclsqlite.c.  We need it here so that the get_sqlite_pointer routine36** can extract the sqlite3* pointer from an existing Tcl SQLite37** connection.38*/39struct SqliteDb {40  sqlite3 *db;41};42 43/*44** Convert text generated by the "%p" conversion format back into45** a pointer.46*/47static int testHexToInt(int h){48  if( h>='0' && h<='9' ){49    return h - '0';50  }else if( h>='a' && h<='f' ){51    return h - 'a' + 10;52  }else{53    assert( h>='A' && h<='F' );54    return h - 'A' + 10;55  }56}57void *sqlite3TestTextToPtr(const char *z){58  void *p;59  u64 v;60  u32 v2;61  if( z[0]=='0' && z[1]=='x' ){62    z += 2;63  }64  v = 0;65  while( *z ){66    v = (v<<4) + testHexToInt(*z);67    z++;68  }69  if( sizeof(p)==sizeof(v) ){70    memcpy(&p, &v, sizeof(p));71  }else{72    assert( sizeof(p)==sizeof(v2) );73    v2 = (u32)v;74    memcpy(&p, &v2, sizeof(p));75  }76  return p;77}78 79 80/*81** A TCL command that returns the address of the sqlite* pointer82** for an sqlite connection instance.  Bad things happen if the83** input is not an sqlite connection.84*/85static int SQLITE_TCLAPI get_sqlite_pointer(86  void * clientData,87  Tcl_Interp *interp,88  int objc,89  Tcl_Obj *CONST objv[]90){91  struct SqliteDb *p;92  Tcl_CmdInfo cmdInfo;93  char zBuf[100];94  if( objc!=2 ){95    Tcl_WrongNumArgs(interp, 1, objv, "SQLITE-CONNECTION");96    return TCL_ERROR;97  }98  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){99    Tcl_AppendResult(interp, "command not found: ",100           Tcl_GetString(objv[1]), (char*)0);101    return TCL_ERROR;102  }103  p = (struct SqliteDb*)cmdInfo.objClientData;104  sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p->db);105  Tcl_AppendResult(interp, zBuf, NULL);106  return TCL_OK;107}108 109/*110** Decode a pointer to an sqlite3 object.111*/112int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){113  struct SqliteDb *p;114  Tcl_CmdInfo cmdInfo;115  if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){116    p = (struct SqliteDb*)cmdInfo.objClientData;117    *ppDb = p->db;118  }else{119    *ppDb = (sqlite3*)sqlite3TestTextToPtr(zA);120  }121  return TCL_OK;122}123 124#if SQLITE_OS_WIN125/*126** Decode a Win32 HANDLE object.127*/128int getWin32Handle(Tcl_Interp *interp, const char *zA, LPHANDLE phFile){129  *phFile = (HANDLE)sqlite3TestTextToPtr(zA);130  return TCL_OK;131}132#endif133 134extern const char *sqlite3ErrName(int);135#define t1ErrorName sqlite3ErrName136 137/*138** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the139** fact that the sqlite3* is the first field in the Vdbe structure.140*/141#define StmtToDb(X)   sqlite3_db_handle(X)142 143/*144** Check a return value to make sure it agrees with the results145** from sqlite3_errcode.146*/147int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){148  if( sqlite3_threadsafe()==0 && rc!=SQLITE_MISUSE && rc!=SQLITE_OK149   && sqlite3_errcode(db)!=rc ){150    char zBuf[200];151    int r2 = sqlite3_errcode(db);152    sqlite3_snprintf(sizeof(zBuf), zBuf,153       "error code %s (%d) does not match sqlite3_errcode %s (%d)",154       t1ErrorName(rc), rc, t1ErrorName(r2), r2);155    Tcl_ResetResult(interp);156    Tcl_AppendResult(interp, zBuf, NULL);157    return 1;158  }159  return 0;160}161 162/*163** Decode a pointer to an sqlite3_stmt object.164*/165static int getStmtPointer(166  Tcl_Interp *interp, 167  const char *zArg,  168  sqlite3_stmt **ppStmt169){170  *ppStmt = (sqlite3_stmt*)sqlite3TestTextToPtr(zArg);171  return TCL_OK;172}173 174/*175** Generate a text representation of a pointer that can be understood176** by the getDbPointer and getVmPointer routines above.177**178** The problem is, on some machines (Solaris) if you do a printf with179** "%p" you cannot turn around and do a scanf with the same "%p" and180** get your pointer back.  You have to prepend a "0x" before it will181** work.  Or at least that is what is reported to me (drh).  But this182** behavior varies from machine to machine.  The solution used her is183** to test the string right after it is generated to see if it can be184** understood by scanf, and if not, try prepending an "0x" to see if185** that helps.  If nothing works, a fatal error is generated.186*/187int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p){188  sqlite3_snprintf(100, zPtr, "%p", p);189  return TCL_OK;190}191 192/*193** The callback routine for sqlite3_exec_printf().194*/195static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){196  Tcl_DString *str = (Tcl_DString*)pArg;197  int i;198 199  if( Tcl_DStringLength(str)==0 ){200    for(i=0; i<argc; i++){201      Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");202    }203  }204  for(i=0; i<argc; i++){205    Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");206  }207  return 0;208}209 210/*211** The I/O tracing callback.212*/213#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)214static FILE *iotrace_file = 0;215static void io_trace_callback(const char *zFormat, ...){216  va_list ap;217  va_start(ap, zFormat);218  vfprintf(iotrace_file, zFormat, ap);219  va_end(ap);220  fflush(iotrace_file);221}222#endif223 224/*225** Usage:  io_trace FILENAME226**227** Turn I/O tracing on or off.  If FILENAME is not an empty string,228** I/O tracing begins going into FILENAME. If FILENAME is an empty229** string, I/O tracing is turned off.230*/231static int SQLITE_TCLAPI test_io_trace(232  void *NotUsed,233  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */234  int argc,              /* Number of arguments */235  char **argv            /* Text of each argument */236){237#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)238  if( argc!=2 ){239    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],240          " FILENAME\"", 0);241    return TCL_ERROR;242  }243  if( iotrace_file ){244    if( iotrace_file!=stdout && iotrace_file!=stderr ){245      fclose(iotrace_file);246    }247    iotrace_file = 0;248    sqlite3IoTrace = 0;249  }250  if( argv[1][0] ){251    if( strcmp(argv[1],"stdout")==0 ){252      iotrace_file = stdout;253    }else if( strcmp(argv[1],"stderr")==0 ){254      iotrace_file = stderr;255    }else{256      iotrace_file = fopen(argv[1], "w");257    }258    sqlite3IoTrace = io_trace_callback;259  }260#endif261  return TCL_OK;262}263 264/*265** Usage:  clang_sanitize_address 266**267** Returns true if the program was compiled using clang with the 268** -fsanitize=address switch on the command line. False otherwise.269**270** Also return true if the OMIT_MISUSE environment variable exists.271*/272static int SQLITE_TCLAPI clang_sanitize_address(273  void *NotUsed,274  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */275  int argc,              /* Number of arguments */276  char **argv            /* Text of each argument */277){278  int res = 0;279#if defined(__has_feature)280# if __has_feature(address_sanitizer)281  res = 1;282# endif283#endif284#ifdef __SANITIZE_ADDRESS__285  res = 1;286#endif287  if( res==0 && getenv("OMIT_MISUSE")!=0 ) res = 1;288  Tcl_SetObjResult(interp, Tcl_NewIntObj(res));289  return TCL_OK;290}291  292/*293** Usage:  sqlite3_exec_printf  DB  FORMAT  STRING294**295** Invoke the sqlite3_exec_printf() interface using the open database296** DB.  The SQL is the string FORMAT.  The format string should contain297** one %s or %q.  STRING is the value inserted into %s or %q.298*/299static int SQLITE_TCLAPI test_exec_printf(300  void *NotUsed,301  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */302  int argc,              /* Number of arguments */303  char **argv            /* Text of each argument */304){305  sqlite3 *db;306  Tcl_DString str;307  int rc;308  char *zErr = 0;309  char *zSql;310  char zBuf[30];311  if( argc!=4 ){312    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 313       " DB FORMAT STRING", 0);314    return TCL_ERROR;315  }316  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;317  Tcl_DStringInit(&str);318  zSql = sqlite3_mprintf(argv[2], argv[3]);319  rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);320  sqlite3_free(zSql);321  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);322  Tcl_AppendElement(interp, zBuf);323  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);324  Tcl_DStringFree(&str);325  if( zErr ) sqlite3_free(zErr);326  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;327  return TCL_OK;328}329 330/*331** Usage:  sqlite3_exec_hex  DB  HEX332**333** Invoke the sqlite3_exec() on a string that is obtained by translating334** HEX into ASCII.  Most characters are translated as is.  %HH becomes335** a hex character.336*/337static int SQLITE_TCLAPI test_exec_hex(338  void *NotUsed,339  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */340  int argc,              /* Number of arguments */341  char **argv            /* Text of each argument */342){343  sqlite3 *db;344  Tcl_DString str;345  int rc, i, j;346  char *zErr = 0;347  char *zHex;348  char zSql[501];349  char zBuf[30];350  if( argc!=3 ){351    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 352       " DB HEX", 0);353    return TCL_ERROR;354  }355  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;356  zHex = argv[2];357  for(i=j=0; i<(sizeof(zSql)-1) && zHex[j]; i++, j++){358    if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){359      zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]);360      j += 2;361    }else{362      zSql[i] = zHex[j];363    }364  }365  zSql[i] = 0;366  Tcl_DStringInit(&str);367  rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);368  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);369  Tcl_AppendElement(interp, zBuf);370  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);371  Tcl_DStringFree(&str);372  if( zErr ) sqlite3_free(zErr);373  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;374  return TCL_OK;375}376 377/*378** Usage:  db_enter DB379**         db_leave DB380**381** Enter or leave the mutex on a database connection.382*/383static int SQLITE_TCLAPI db_enter(384  void *NotUsed,385  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */386  int argc,              /* Number of arguments */387  char **argv            /* Text of each argument */388){389  sqlite3 *db;390  if( argc!=2 ){391    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 392       " DB", 0);393    return TCL_ERROR;394  }395  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;396  sqlite3_mutex_enter(db->mutex);397  return TCL_OK;398}399static int SQLITE_TCLAPI db_leave(400  void *NotUsed,401  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */402  int argc,              /* Number of arguments */403  char **argv            /* Text of each argument */404){405  sqlite3 *db;406  if( argc!=2 ){407    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 408       " DB", 0);409    return TCL_ERROR;410  }411  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;412  sqlite3_mutex_leave(db->mutex);413  return TCL_OK;414}415 416/*417** Usage:  sqlite3_exec  DB  SQL418**419** Invoke the sqlite3_exec interface using the open database DB420*/421static int SQLITE_TCLAPI test_exec(422  void *NotUsed,423  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */424  int argc,              /* Number of arguments */425  char **argv            /* Text of each argument */426){427  sqlite3 *db;428  Tcl_DString str;429  int rc;430  char *zErr = 0;431  char *zSql;432  int i, j;433  char zBuf[30];434  if( argc!=3 ){435    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 436       " DB SQL", 0);437    return TCL_ERROR;438  }439  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;440  Tcl_DStringInit(&str);441  zSql = sqlite3_mprintf("%s", argv[2]);442  for(i=j=0; zSql[i];){443    if( zSql[i]=='%' ){444      zSql[j++] = (testHexToInt(zSql[i+1])<<4) + testHexToInt(zSql[i+2]);445      i += 3;446    }else{447      zSql[j++] = zSql[i++];448    }449  }450  zSql[j] = 0;451  rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);452  sqlite3_free(zSql);453  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);454  Tcl_AppendElement(interp, zBuf);455  Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);456  Tcl_DStringFree(&str);457  if( zErr ) sqlite3_free(zErr);458  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;459  return TCL_OK;460}461 462/*463** Usage:  sqlite3_exec_nr  DB  SQL464**465** Invoke the sqlite3_exec interface using the open database DB.  Discard466** all results467*/468static int SQLITE_TCLAPI test_exec_nr(469  void *NotUsed,470  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */471  int argc,              /* Number of arguments */472  char **argv            /* Text of each argument */473){474  sqlite3 *db;475  int rc;476  char *zErr = 0;477  if( argc!=3 ){478    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 479       " DB SQL", 0);480    return TCL_ERROR;481  }482  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;483  rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);484  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;485  return TCL_OK;486}487 488/*489** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...490**491** Test the %z format of sqlite_mprintf().  Use multiple mprintf() calls to 492** concatenate arg0 through argn using separator as the separator.493** Return the result.494*/495static int SQLITE_TCLAPI test_mprintf_z(496  void *NotUsed,497  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */498  int argc,              /* Number of arguments */499  char **argv            /* Text of each argument */500){501  char *zResult = 0;502  int i;503 504  for(i=2; i<argc && (i==2 || zResult); i++){505    zResult = sqlite3_mprintf("%z%s%s", zResult, argv[1], argv[i]);506  }507  Tcl_AppendResult(interp, zResult, NULL);508  sqlite3_free(zResult);509  return TCL_OK;510}511 512/*513** Usage:  sqlite3_mprintf_n_test  STRING514**515** Test the %n format of sqlite_mprintf().  Return the length of the516** input string.517*/518static int SQLITE_TCLAPI test_mprintf_n(519  void *NotUsed,520  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */521  int argc,              /* Number of arguments */522  char **argv            /* Text of each argument */523){524  char *zStr;525  int n = 0;526  zStr = sqlite3_mprintf("%s%n", argv[1], &n);527  sqlite3_free(zStr);528  Tcl_SetObjResult(interp, Tcl_NewIntObj(n));529  return TCL_OK;530}531 532/*533** Usage:  sqlite3_snprintf_int  SIZE FORMAT  INT534**535** Test the of sqlite3_snprintf() routine.  SIZE is the size of the536** output buffer in bytes.  The maximum size is 100.  FORMAT is the537** format string.  INT is a single integer argument.  The FORMAT538** string must require no more than this one integer argument.  If539** You pass in a format string that requires more than one argument,540** bad things will happen.541*/542static int SQLITE_TCLAPI test_snprintf_int(543  void *NotUsed,544  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */545  int argc,              /* Number of arguments */546  char **argv            /* Text of each argument */547){548  char zStr[100];549  int n = atoi(argv[1]);550  const char *zFormat = argv[2];551  int a1 = atoi(argv[3]);552  if( n>sizeof(zStr) ) n = sizeof(zStr);553  sqlite3_snprintf(sizeof(zStr), zStr, "abcdefghijklmnopqrstuvwxyz");554  sqlite3_snprintf(n, zStr, zFormat, a1);555  Tcl_AppendResult(interp, zStr, NULL);556  return TCL_OK;557}558 559#ifndef SQLITE_OMIT_GET_TABLE560 561/*562** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING  ?--no-counts?563**564** Invoke the sqlite3_get_table_printf() interface using the open database565** DB.  The SQL is the string FORMAT.  The format string should contain566** one %s or %q.  STRING is the value inserted into %s or %q.567*/568static int SQLITE_TCLAPI test_get_table_printf(569  void *NotUsed,570  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */571  int argc,              /* Number of arguments */572  char **argv            /* Text of each argument */573){574  sqlite3 *db;575  Tcl_DString str;576  int rc;577  char *zErr = 0;578  int nRow = 0, nCol = 0;579  char **aResult;580  int i;581  char zBuf[30];582  char *zSql;583  int resCount = -1;584  if( argc==5 ){585    if( Tcl_GetInt(interp, argv[4], &resCount) ) return TCL_ERROR;586  }587  if( argc!=4 && argc!=5 ){588    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 589       " DB FORMAT STRING ?COUNT?", 0);590    return TCL_ERROR;591  }592  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;593  Tcl_DStringInit(&str);594  zSql = sqlite3_mprintf(argv[2],argv[3]);595  if( argc==5 ){596    rc = sqlite3_get_table(db, zSql, &aResult, 0, 0, &zErr);597  }else{598    rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);599    resCount = (nRow+1)*nCol;600  }601  sqlite3_free(zSql);602  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);603  Tcl_ResetResult(interp);604  Tcl_AppendElement(interp, zBuf);605  if( rc==SQLITE_OK ){606    if( argc==4 ){607      sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nRow);608      Tcl_AppendElement(interp, zBuf);609      sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nCol);610      Tcl_AppendElement(interp, zBuf);611    }612    for(i=0; i<resCount; i++){613      Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");614    }615  }else{616    Tcl_AppendElement(interp, zErr);617  }618  sqlite3_free_table(aResult);619  if( zErr ) sqlite3_free(zErr);620  if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;621  return TCL_OK;622}623 624#endif /* SQLITE_OMIT_GET_TABLE */625 626 627/*628** Usage:  sqlite3_last_insert_rowid DB629**630** Returns the integer ROWID of the most recent insert.631*/632static int SQLITE_TCLAPI test_last_rowid(633  void *NotUsed,634  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */635  int argc,              /* Number of arguments */636  char **argv            /* Text of each argument */637){638  sqlite3 *db;639  char zBuf[30];640 641  if( argc!=2 ){642    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", NULL);643    return TCL_ERROR;644  }645  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;646  sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", sqlite3_last_insert_rowid(db));647  Tcl_AppendResult(interp, zBuf, NULL);648  return SQLITE_OK;649}650 651/*652** Usage:  sqlite3_key DB KEY653**654** Set the codec key.655*/656static int SQLITE_TCLAPI test_key(657  void *NotUsed,658  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */659  int argc,              /* Number of arguments */660  char **argv            /* Text of each argument */661){662  return TCL_OK;663}664 665/*666** Usage:  sqlite3_rekey DB KEY667**668** Change the codec key.669*/670static int SQLITE_TCLAPI test_rekey(671  void *NotUsed,672  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */673  int argc,              /* Number of arguments */674  char **argv            /* Text of each argument */675){676  return TCL_OK;677}678 679/*680** Usage:  sqlite3_close DB681**682** Closes the database opened by sqlite3_open.683*/684static int SQLITE_TCLAPI sqlite_test_close(685  void *NotUsed,686  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */687  int argc,              /* Number of arguments */688  char **argv            /* Text of each argument */689){690  sqlite3 *db;691  int rc;692  if( argc!=2 ){693    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],694       " FILENAME\"", 0);695    return TCL_ERROR;696  }697  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;698  rc = sqlite3_close(db);699  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);700  return TCL_OK;701}702 703/*704** Usage:  sqlite3_close_v2 DB705**706** Closes the database opened by sqlite3_open.707*/708static int SQLITE_TCLAPI sqlite_test_close_v2(709  void *NotUsed,710  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */711  int argc,              /* Number of arguments */712  char **argv            /* Text of each argument */713){714  sqlite3 *db;715  int rc;716  if( argc!=2 ){717    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],718       " FILENAME\"", 0);719    return TCL_ERROR;720  }721  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;722  rc = sqlite3_close_v2(db);723  Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);724  return TCL_OK;725}726 727/*728** Implementation of the x_coalesce() function.729** Return the first argument non-NULL argument.730*/731static void t1_ifnullFunc(732  sqlite3_context *context,733  int argc,734  sqlite3_value **argv735){736  int i;737  for(i=0; i<argc; i++){738    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){739      int n = sqlite3_value_bytes(argv[i]);740      sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]),741          n, SQLITE_TRANSIENT);742      break;743    }744  }745}746 747/*748** These are test functions.    hex8() interprets its argument as749** UTF8 and returns a hex encoding.  hex16le() interprets its argument750** as UTF16le and returns a hex encoding.751*/752static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){753  const unsigned char *z;754  int i;755  char zBuf[200];756  z = sqlite3_value_text(argv[0]);757  for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){758    sqlite3_snprintf(sizeof(zBuf)-i*2, &zBuf[i*2], "%02x", z[i]);759  }760  zBuf[i*2] = 0;761  sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);762}763#ifndef SQLITE_OMIT_UTF16764static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){765  const unsigned short int *z;766  int i;767  char zBuf[400];768  z = sqlite3_value_text16(argv[0]);769  for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){770    sqlite3_snprintf(sizeof(zBuf)-i*4, &zBuf[i*4],"%04x", z[i]&0xff);771  }772  zBuf[i*4] = 0;773  sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);774}775#endif776 777/*778** A structure into which to accumulate text.779*/780struct dstr {781  int nAlloc;  /* Space allocated */782  int nUsed;   /* Space used */783  char *z;     /* The space */784};785 786/*787** Append text to a dstr788*/789static void dstrAppend(struct dstr *p, const char *z, int divider){790  int n = (int)strlen(z);791  if( p->nUsed + n + 2 > p->nAlloc ){792    char *zNew;793    p->nAlloc = p->nAlloc*2 + n + 200;794    zNew = sqlite3_realloc(p->z, p->nAlloc);795    if( zNew==0 ){796      sqlite3_free(p->z);797      memset(p, 0, sizeof(*p));798      return;799    }800    p->z = zNew;801  }802  if( divider && p->nUsed>0 ){803    p->z[p->nUsed++] = divider;804  }805  memcpy(&p->z[p->nUsed], z, n+1);806  p->nUsed += n;807}808 809/*810** Invoked for each callback from sqlite3ExecFunc811*/812static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){813  struct dstr *p = (struct dstr*)pData;814  int i;815  for(i=0; i<argc; i++){816    if( argv[i]==0 ){817      dstrAppend(p, "NULL", ' ');818    }else{819      dstrAppend(p, argv[i], ' ');820    }821  }822  return 0;823}824 825/*826** Implementation of the x_sqlite_exec() function.  This function takes827** a single argument and attempts to execute that argument as SQL code.828** This is illegal and should set the SQLITE_MISUSE flag on the database.829**830** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()831** from within a function call.  832** 833** This routine simulates the effect of having two threads attempt to834** use the same database at the same time.835*/836static void sqlite3ExecFunc(837  sqlite3_context *context, 838  int argc,  839  sqlite3_value **argv840){841  struct dstr x;842  memset(&x, 0, sizeof(x));843  (void)sqlite3_exec((sqlite3*)sqlite3_user_data(context),844      (char*)sqlite3_value_text(argv[0]),845      execFuncCallback, &x, 0);846  sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT);847  sqlite3_free(x.z);848}849 850/*851** Implementation of tkt2213func(), a scalar function that takes exactly852** one argument. It has two interesting features:853**854** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*.855**   If the three pointers returned are not the same an SQL error is raised.856**857** * Otherwise it returns a copy of the text representation of its 858**   argument in such a way as the VDBE representation is a Mem* cell 859**   with the MEM_Term flag clear. 860**861** Ticket #2213 can therefore be tested by evaluating the following862** SQL expression:863**864**   tkt2213func(tkt2213func('a string'));865*/866static void tkt2213Function(867  sqlite3_context *context, 868  int argc,  869  sqlite3_value **argv870){871  int nText;872  unsigned char const *zText1;873  unsigned char const *zText2;874  unsigned char const *zText3;875 876  nText = sqlite3_value_bytes(argv[0]);877  zText1 = sqlite3_value_text(argv[0]);878  zText2 = sqlite3_value_text(argv[0]);879  zText3 = sqlite3_value_text(argv[0]);880 881  if( zText1!=zText2 || zText2!=zText3 ){882    sqlite3_result_error(context, "tkt2213 is not fixed", -1);883  }else{884    char *zCopy = (char *)sqlite3_malloc(nText);885    memcpy(zCopy, zText1, nText);886    sqlite3_result_text(context, zCopy, nText, sqlite3_free);887  }888}889 890/*891** The following SQL function takes 4 arguments.  The 2nd and892** 4th argument must be one of these strings:  'text', 'text16',893** or 'blob' corresponding to API functions894**895**      sqlite3_value_text()896**      sqlite3_value_text16()897**      sqlite3_value_blob()898**899** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',900** corresponding to APIs:901**902**      sqlite3_value_bytes()903**      sqlite3_value_bytes16()904**      noop905**906** The APIs designated by the 2nd through 4th arguments are applied907** to the first argument in order.  If the pointers returned by the908** second and fourth are different, this routine returns 1.  Otherwise,909** this routine returns 0.910**911** This function is used to test to see when returned pointers from912** the _text(), _text16() and _blob() APIs become invalidated.913*/914static void ptrChngFunction(915  sqlite3_context *context, 916  int argc,  917  sqlite3_value **argv918){919  const void *p1, *p2;920  const char *zCmd;921  if( argc!=4 ) return;922  zCmd = (const char*)sqlite3_value_text(argv[1]);923  if( zCmd==0 ) return;924  if( strcmp(zCmd,"text")==0 ){925    p1 = (const void*)sqlite3_value_text(argv[0]);926#ifndef SQLITE_OMIT_UTF16927  }else if( strcmp(zCmd, "text16")==0 ){928    p1 = (const void*)sqlite3_value_text16(argv[0]);929#endif930  }else if( strcmp(zCmd, "blob")==0 ){931    p1 = (const void*)sqlite3_value_blob(argv[0]);932  }else{933    return;934  }935  zCmd = (const char*)sqlite3_value_text(argv[2]);936  if( zCmd==0 ) return;937  if( strcmp(zCmd,"bytes")==0 ){938    sqlite3_value_bytes(argv[0]);939#ifndef SQLITE_OMIT_UTF16940  }else if( strcmp(zCmd, "bytes16")==0 ){941    sqlite3_value_bytes16(argv[0]);942#endif943  }else if( strcmp(zCmd, "noop")==0 ){944    /* do nothing */945  }else{946    return;947  }948  zCmd = (const char*)sqlite3_value_text(argv[3]);949  if( zCmd==0 ) return;950  if( strcmp(zCmd,"text")==0 ){951    p2 = (const void*)sqlite3_value_text(argv[0]);952#ifndef SQLITE_OMIT_UTF16953  }else if( strcmp(zCmd, "text16")==0 ){954    p2 = (const void*)sqlite3_value_text16(argv[0]);955#endif956  }else if( strcmp(zCmd, "blob")==0 ){957    p2 = (const void*)sqlite3_value_blob(argv[0]);958  }else{959    return;960  }961  sqlite3_result_int(context, p1!=p2);962}963 964/*965** This SQL function returns a different answer each time it is called, even if966** the arguments are the same.967*/968static void nondeterministicFunction(969  sqlite3_context *context, 970  int argc,  971  sqlite3_value **argv972){973  static int cnt = 0;974  sqlite3_result_int(context, cnt++);975}976 977/*978** This SQL function returns the integer value of its argument as a MEM_IntReal979** value.980*/981static void intrealFunction(982  sqlite3_context *context, 983  int argc,  984  sqlite3_value **argv985){986  sqlite3_int64 v = sqlite3_value_int64(argv[0]);987  sqlite3_result_int64(context, v);988  sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context);989}990 991/*992** These SQL functions attempt to return a value (their first argument)993** that has been modified to have multiple datatypes.  For example both994** TEXT and INTEGER.995*/996static void addTextTypeFunction(997  sqlite3_context *context, 998  int argc,  999  sqlite3_value **argv1000){1001  (void)sqlite3_value_text(argv[0]);1002  (void)argc;1003  sqlite3_result_value(context, argv[0]);1004}1005static void addIntTypeFunction(1006  sqlite3_context *context, 1007  int argc,  1008  sqlite3_value **argv1009){1010  (void)sqlite3_value_int64(argv[0]);1011  (void)argc;1012  sqlite3_result_value(context, argv[0]);1013}1014static void addRealTypeFunction(1015  sqlite3_context *context, 1016  int argc,  1017  sqlite3_value **argv1018){1019  (void)sqlite3_value_double(argv[0]);1020  (void)argc;1021  sqlite3_result_value(context, argv[0]);1022}1023 1024/*1025** SQL function:  strtod(X)1026**1027** Use the C-library strtod() function to convert string X into a double.1028** Used for comparing the accuracy of SQLite's internal text-to-float conversion1029** routines against the C-library.1030*/1031static void shellStrtod(1032  sqlite3_context *pCtx,1033  int nVal,1034  sqlite3_value **apVal1035){1036  char *z = (char*)sqlite3_value_text(apVal[0]);1037  UNUSED_PARAMETER(nVal);1038  if( z==0 ) return;1039  sqlite3_result_double(pCtx, strtod(z,0));1040}1041 1042/*1043** SQL function:  dtostr(X)1044**1045** Use the C-library printf() function to convert real value X into a string.1046** Used for comparing the accuracy of SQLite's internal float-to-text conversion1047** routines against the C-library.1048*/1049static void shellDtostr(1050  sqlite3_context *pCtx,1051  int nVal,1052  sqlite3_value **apVal1053){1054  double r = sqlite3_value_double(apVal[0]);1055  int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;1056  char z[400];1057  if( n<1 ) n = 1;1058  if( n>350 ) n = 350;1059  sprintf(z, "%#+.*e", n, r);1060  sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);1061}1062 1063/*1064** We need a method for setting the pointer values created by the1065** intarray_addr, int64array_addr, doublearray_addr, and textarray_addr1066** routines below.  The inttoptr(X) SQL function accomplishes1067** this.  Tcl scripts will bind an array address as an integer X and1068** the inttoptr() SQL function will use sqlite3_result_pointer() to1069** convert that integer into a pointer usable by carray().1070*/1071static void inttoptrFunc(1072  sqlite3_context *context,1073  int argc,1074  sqlite3_value **argv1075){1076  void *p;1077  sqlite3_int64 i64;1078  i64 = sqlite3_value_int64(argv[0]);1079  if( sizeof(i64)==sizeof(p) ){1080    memcpy(&p, &i64, sizeof(p));1081  }else{1082    int i32 = i64 & 0xffffffff;1083    memcpy(&p, &i32, sizeof(p));1084  }1085  sqlite3_result_pointer(context, p, "carray", 0);1086}1087 1088/*1089** Usage:  sqlite3_create_function DB1090**1091** Call the sqlite3_create_function API on the given database in order1092** to create a function named "x_coalesce".  This function does the same thing1093** as the "coalesce" function.  This function also registers an SQL function1094** named "x_sqlite_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()1095** in this way is illegal recursion and should raise an SQLITE_MISUSE error.1096** The effect is similar to trying to use the same database connection from1097** two threads at the same time.1098**1099** The original motivation for this routine was to be able to call the1100** sqlite3_create_function function while a query is in progress in order1101** to test the SQLITE_MISUSE detection logic.  It is now also used to register1102** a bunch of SQL functions that are useful for testing.1103*/1104static int SQLITE_TCLAPI test_create_function(1105  void *NotUsed,1106  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */1107  int argc,              /* Number of arguments */1108  char **argv            /* Text of each argument */1109){1110  int rc;1111  sqlite3 *db;1112 1113  if( argc!=2 ){1114    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],1115       " DB\"", 0);1116    return TCL_ERROR;1117  }1118  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;1119  rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0, 1120        t1_ifnullFunc, 0, 0);1121  if( rc==SQLITE_OK ){1122    rc = sqlite3_create_function(db, "hex8", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,1123          0, hex8Func, 0, 0);1124  }1125#ifndef SQLITE_OMIT_UTF161126  if( rc==SQLITE_OK ){1127    rc = sqlite3_create_function(db, "hex16", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC,1128          0, hex16Func, 0, 0);1129  }1130#endif1131  if( rc==SQLITE_OK ){1132    rc = sqlite3_create_function(db, "tkt2213func", 1, SQLITE_ANY, 0, 1133          tkt2213Function, 0, 0);1134  }1135  if( rc==SQLITE_OK ){1136    rc = sqlite3_create_function(db, "pointer_change", 4, SQLITE_ANY, 0, 1137          ptrChngFunction, 0, 0);1138  }1139 1140  /* Functions counter1() and counter2() have the same implementation - they1141  ** both return an ascending integer with each call.  But counter1() is marked1142  ** as non-deterministic and counter2() is marked as deterministic.1143  */1144  if( rc==SQLITE_OK ){1145    rc = sqlite3_create_function(db, "counter1", -1, SQLITE_UTF8,1146          0, nondeterministicFunction, 0, 0);1147  }1148  if( rc==SQLITE_OK ){1149    rc = sqlite3_create_function(db, "counter2", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC,1150          0, nondeterministicFunction, 0, 0);1151  }1152 1153  /* The intreal() function converts its argument to an integer and returns1154  ** it as a MEM_IntReal.1155  */1156  if( rc==SQLITE_OK ){1157    rc = sqlite3_create_function(db, "intreal", 1, SQLITE_UTF8,1158          0, intrealFunction, 0, 0);1159  }1160 1161  /* The add_text_type(), add_int_type(), and add_real_type() functions1162  ** attempt to return a value that has multiple datatypes.1163  */1164  if( rc==SQLITE_OK ){1165    rc = sqlite3_create_function(db, "add_text_type", 1, SQLITE_UTF8,1166          0, addTextTypeFunction, 0, 0);1167  }1168  if( rc==SQLITE_OK ){1169    rc = sqlite3_create_function(db, "add_int_type", 1, SQLITE_UTF8,1170          0, addIntTypeFunction, 0, 0);1171  }1172  if( rc==SQLITE_OK ){1173    rc = sqlite3_create_function(db, "add_real_type", 1, SQLITE_UTF8,1174          0, addRealTypeFunction, 0, 0);1175  }1176 1177  /* Functions strtod() and dtostr() work as in the shell.  These routines1178  ** use the standard C library to convert between floating point and1179  ** text.  This is used to compare SQLite's internal conversion routines1180  ** against the standard library conversion routines.1181  **1182  ** Both routines copy/pasted from the shell.c.in implementation1183  ** on 2023-07-03.1184  */1185  if( rc==SQLITE_OK ){1186    rc = sqlite3_create_function(db, "strtod", 1, SQLITE_UTF8, 0,1187                                 shellStrtod, 0, 0);1188  }1189  if( rc==SQLITE_OK ){1190    rc = sqlite3_create_function(db, "dtostr", 1, SQLITE_UTF8, 0,1191                                 shellDtostr, 0, 0);1192  }1193  if( rc==SQLITE_OK ){1194    rc = sqlite3_create_function(db, "dtostr", 2, SQLITE_UTF8, 0,1195                                 shellDtostr, 0, 0);1196  }1197  if( rc==SQLITE_OK ){1198    rc = sqlite3_create_function(db, "inttoptr", 1, SQLITE_UTF8, 0,1199                                 inttoptrFunc, 0, 0);1200  }

Showing the first 1,200 of 9431 lines. Download the file for the rest.