AryaWu/sqlite
0
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 }