diff -r 5f8e5adbbed9 -r 29cda98b007e engine/sqlite/src/vdbeapi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/sqlite/src/vdbeapi.cpp Thu Feb 25 14:29:19 2010 +0000 @@ -0,0 +1,1087 @@ +/* +** 2004 May 26 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file contains code use to implement APIs that are part of the +** VDBE. +*/ +#include "sqliteInt.h" +#include "vdbeInt.h" + +/* +** Return TRUE (non-zero) of the statement supplied as an argument needs +** to be recompiled. A statement needs to be recompiled whenever the +** execution environment changes in a way that would alter the program +** that sqlite3_prepare() generates. For example, if new functions or +** collating sequences are registered or if an authorizer function is +** added or changed. +*/ +EXPORT_C int sqlite3_expired(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p==0 || p->expired; +} + +/* +** The following routine destroys a virtual machine that is created by +** the sqlite3_compile() routine. The integer returned is an SQLITE_ +** success/failure code that describes the result of executing the virtual +** machine. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +EXPORT_C int sqlite3_finalize(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3_mutex *mutex = v->db->mutex; + sqlite3_mutex_enter(mutex); + rc = sqlite3VdbeFinalize(v); + sqlite3_mutex_leave(mutex); + } + return rc; +} + +/* +** Terminate the current execution of an SQL statement and reset it +** back to its starting state so that it can be reused. A success code from +** the prior execution is returned. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +EXPORT_C int sqlite3_reset(sqlite3_stmt *pStmt){ + int rc; + if( pStmt==0 ){ + rc = SQLITE_OK; + }else{ + Vdbe *v = (Vdbe*)pStmt; + sqlite3_mutex_enter(v->db->mutex); + rc = sqlite3VdbeReset(v); + sqlite3VdbeMakeReady(v, -1, 0, 0, 0); + assert( (rc & (v->db->errMask))==rc ); + sqlite3_mutex_leave(v->db->mutex); + } + return rc; +} + +/* +** Set all the parameters in the compiled SQL statement to NULL. +*/ +EXPORT_C int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ + int i; + int rc = SQLITE_OK; + Vdbe *v = (Vdbe*)pStmt; + sqlite3_mutex_enter(v->db->mutex); + for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){ + rc = sqlite3_bind_null(pStmt, i); + } + sqlite3_mutex_leave(v->db->mutex); + return rc; +} + + +/**************************** sqlite3_value_ ******************************* +** The following routines extract information from a Mem or sqlite3_value +** structure. +*/ +EXPORT_C const void *sqlite3_value_blob(sqlite3_value *pVal){ + Mem *p = (Mem*)pVal; + if( p->flags & (MEM_Blob|MEM_Str) ){ + sqlite3VdbeMemExpandBlob(p); + p->flags &= ~MEM_Str; + p->flags |= MEM_Blob; + return p->z; + }else{ + return sqlite3_value_text(pVal); + } +} +EXPORT_C int sqlite3_value_bytes(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF8); +} +EXPORT_C int sqlite3_value_bytes16(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); +} +EXPORT_C double sqlite3_value_double(sqlite3_value *pVal){ + return sqlite3VdbeRealValue((Mem*)pVal); +} +EXPORT_C int sqlite3_value_int(sqlite3_value *pVal){ + return sqlite3VdbeIntValue((Mem*)pVal); +} +EXPORT_C sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ + return sqlite3VdbeIntValue((Mem*)pVal); +} +EXPORT_C const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ + return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C const void *sqlite3_value_text16(sqlite3_value* pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); +} +EXPORT_C const void *sqlite3_value_text16be(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16BE); +} +EXPORT_C const void *sqlite3_value_text16le(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16LE); +} +#endif /* SQLITE_OMIT_UTF16 */ +EXPORT_C int sqlite3_value_type(sqlite3_value* pVal){ + return pVal->type; +} + +/**************************** sqlite3_result_ ******************************* +** The following routines are used by user-defined functions to specify +** the function result. +*/ +EXPORT_C void sqlite3_result_blob( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( n>=0 ); + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetStr(&pCtx->s, (const char*)z, n, 0, xDel); +} +EXPORT_C void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetDouble(&pCtx->s, rVal); +} +EXPORT_C void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + pCtx->isError = 1; + sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + pCtx->isError = 1; + sqlite3VdbeMemSetStr(&pCtx->s, (const char*)z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); +} +#endif +EXPORT_C void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal); +} +EXPORT_C void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetInt64(&pCtx->s, iVal); +} +EXPORT_C void sqlite3_result_null(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetNull(&pCtx->s); +} +EXPORT_C void sqlite3_result_text( + sqlite3_context *pCtx, + const char *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel); +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C void sqlite3_result_text16( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetStr(&pCtx->s, (const char*)z, n, SQLITE_UTF16NATIVE, xDel); +} +EXPORT_C void sqlite3_result_text16be( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetStr(&pCtx->s, (const char*)z, n, SQLITE_UTF16BE, xDel); +} +EXPORT_C void sqlite3_result_text16le( + sqlite3_context *pCtx, + const void *z, + int n, + void (*xDel)(void *) +){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetStr(&pCtx->s, (const char*)z, n, SQLITE_UTF16LE, xDel); +} +#endif /* SQLITE_OMIT_UTF16 */ +EXPORT_C void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemCopy(&pCtx->s, pValue); +} +EXPORT_C void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetZeroBlob(&pCtx->s, n); +} + +/* Force an SQLITE_TOOBIG error. */ +EXPORT_C void sqlite3_result_error_toobig(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetZeroBlob(&pCtx->s, SQLITE_MAX_LENGTH+1); +} + +/* An SQLITE_NOMEM error. */ +EXPORT_C void sqlite3_result_error_nomem(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + sqlite3VdbeMemSetNull(&pCtx->s); + pCtx->isError = 1; + pCtx->s.db->mallocFailed = 1; +} + +/* +** Execute the statement pStmt, either until a row of data is ready, the +** statement is completely executed or an error occurs. +** +** This routine implements the bulk of the logic behind the sqlite_step() +** API. The only thing omitted is the automatic recompile if a +** schema change has occurred. That detail is handled by the +** outer sqlite3_step() wrapper procedure. +*/ +static int sqlite3Step(Vdbe *p){ + sqlite3 *db; + int rc; + + assert(p); + if( p->magic!=VDBE_MAGIC_RUN ){ + return SQLITE_MISUSE; + } + + /* Assert that malloc() has not failed */ + db = p->db; + assert( !db->mallocFailed ); + + if( p->aborted ){ + return SQLITE_ABORT; + } + if( p->pc<=0 && p->expired ){ + if( p->rc==SQLITE_OK ){ + p->rc = SQLITE_SCHEMA; + } + rc = SQLITE_ERROR; + goto end_of_step; + } + if( sqlite3SafetyOn(db) ){ + p->rc = SQLITE_MISUSE; + return SQLITE_MISUSE; + } + if( p->pc<0 ){ + /* If there are no other statements currently running, then + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->activeVdbeCnt==0 ){ + db->u1.isInterrupted = 0; + } + +#ifndef SQLITE_OMIT_TRACE + /* Invoke the trace callback if there is one + */ + if( db->xTrace && !db->init.busy ){ + assert( p->nOp>0 ); + assert( p->aOp[p->nOp-1].opcode==OP_Noop ); + assert( p->aOp[p->nOp-1].p3!=0 ); + assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); + sqlite3SafetyOff(db); + db->xTrace(db->pTraceArg, p->aOp[p->nOp-1].p3); + if( sqlite3SafetyOn(db) ){ + p->rc = SQLITE_MISUSE; + return SQLITE_MISUSE; + } + } + if( db->xProfile && !db->init.busy ){ + double rNow; + sqlite3OsCurrentTime(db->pVfs, &rNow); + p->startTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0; + } +#endif + + /* Print a copy of SQL as it is executed if the SQL_TRACE pragma is turned + ** on in debugging mode. + */ +#ifdef SQLITE_DEBUG + if( (db->flags & SQLITE_SqlTrace)!=0 ){ + sqlite3DebugPrintf("SQL-trace: %s\n", p->aOp[p->nOp-1].p3); + } +#endif /* SQLITE_DEBUG */ + + db->activeVdbeCnt++; + p->pc = 0; + } +#ifndef SQLITE_OMIT_EXPLAIN + if( p->explain ){ + rc = sqlite3VdbeList(p); + }else +#endif /* SQLITE_OMIT_EXPLAIN */ + { + rc = sqlite3VdbeExec(p); + } + + if( sqlite3SafetyOff(db) ){ + rc = SQLITE_MISUSE; + } + +#ifndef SQLITE_OMIT_TRACE + /* Invoke the profile callback if there is one + */ + if( rc!=SQLITE_ROW && db->xProfile && !db->init.busy ){ + double rNow; + u64 elapseTime; + + sqlite3OsCurrentTime(db->pVfs, &rNow); + elapseTime = (rNow - (int)rNow)*3600.0*24.0*1000000000.0 - p->startTime; + assert( p->nOp>0 ); + assert( p->aOp[p->nOp-1].opcode==OP_Noop ); + assert( p->aOp[p->nOp-1].p3!=0 ); + assert( p->aOp[p->nOp-1].p3type==P3_DYNAMIC ); + db->xProfile(db->pProfileArg, p->aOp[p->nOp-1].p3, elapseTime); + } +#endif + + sqlite3Error(p->db, rc, 0); + p->rc = sqlite3ApiExit(p->db, p->rc); +end_of_step: + assert( (rc&0xff)==rc ); + if( p->zSql && (rc&0xff)db, p->rc, 0); + return p->rc; + }else{ + /* This is for legacy sqlite3_prepare() builds and when the code + ** is SQLITE_ROW or SQLITE_DONE */ + return rc; + } +} + +/* +** This is the top-level implementation of sqlite3_step(). Call +** sqlite3Step() to do most of the work. If a schema error occurs, +** call sqlite3Reprepare() and try again. +*/ +#ifdef SQLITE_OMIT_PARSER +int sqlite3_step(sqlite3_stmt *pStmt){ + int rc = SQLITE_MISUSE; + if( pStmt ){ + Vdbe *v; + v = (Vdbe*)pStmt; + sqlite3_mutex_enter(v->db->mutex); + rc = sqlite3Step(v); + sqlite3_mutex_leave(v->db->mutex); + } + return rc; +} +#else +EXPORT_C int sqlite3_step(sqlite3_stmt *pStmt){ + int rc = SQLITE_MISUSE; + if( pStmt ){ + int cnt = 0; + Vdbe *v = (Vdbe*)pStmt; + sqlite3 *db = v->db; + sqlite3_mutex_enter(db->mutex); + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA + && cnt++ < 5 + && sqlite3Reprepare(v) ){ + sqlite3_reset(pStmt); + v->expired = 0; + } + if( rc==SQLITE_SCHEMA && v->zSql && db->pErr ){ + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message + ** from the database handle into the statement and sets the statement + ** program counter to 0 to ensure that when the statement is + ** finalized or reset the parser error message is available via + ** sqlite3_errmsg() and sqlite3_errcode(). + */ + const char *zErr = (const char *)sqlite3_value_text(db->pErr); + sqlite3_free(v->zErrMsg); + if( !db->mallocFailed ){ + v->zErrMsg = sqlite3DbStrDup(db, zErr); + } else { + v->zErrMsg = 0; + v->rc = SQLITE_NOMEM; + } + } + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); + } + return rc; +} +#endif + +/* +** Extract the user data from a sqlite3_context structure and return a +** pointer to it. +*/ +EXPORT_C void *sqlite3_user_data(sqlite3_context *p){ + assert( p && p->pFunc ); + return p->pFunc->pUserData; +} + +/* +** The following is the implementation of an SQL function that always +** fails with an error message stating that the function is used in the +** wrong context. The sqlite3_overload_function() API might construct +** SQL function that use this routine so that the functions will exist +** for name resolution but are actually overloaded by the xFindFunction +** method of virtual tables. +*/ +void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ + int argc, /* Number of arguments to the function */ + sqlite3_value **argv /* Value of each argument */ +){ + const char *zName = context->pFunc->zName; + char *zErr; + zErr = sqlite3MPrintf(0, + "unable to use function %s in the requested context", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); +} + +/* +** Allocate or return the aggregate context for a user function. A new +** context is allocated on the first call. Subsequent calls return the +** same context that was returned on prior calls. +*/ +EXPORT_C void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ + Mem *pMem; + assert( p && p->pFunc && p->pFunc->xStep ); + assert( sqlite3_mutex_held(p->s.db->mutex) ); + pMem = p->pMem; + if( (pMem->flags & MEM_Agg)==0 ){ + if( nByte==0 ){ + assert( pMem->flags==MEM_Null ); + pMem->z = 0; + }else{ + pMem->flags = MEM_Agg; + pMem->xDel = sqlite3_free; + pMem->u.pDef = p->pFunc; + pMem->z = (char*)sqlite3DbMallocZero(p->s.db, nByte); + } + } + return (void*)pMem->z; +} + +/* +** Return the auxilary data pointer, if any, for the iArg'th argument to +** the user-function defined by pCtx. +*/ +EXPORT_C void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ + VdbeFunc *pVdbeFunc; + + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + pVdbeFunc = pCtx->pVdbeFunc; + if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){ + return 0; + } + return pVdbeFunc->apAux[iArg].pAux; +} + +/* +** Set the auxilary data pointer and delete function, for the iArg'th +** argument to the user-function defined by pCtx. Any previous value is +** deleted by calling the delete function specified when it was set. +*/ +EXPORT_C void sqlite3_set_auxdata( + sqlite3_context *pCtx, + int iArg, + void *pAux, + void (*xDelete)(void*) +){ + VdbeFunc::AuxData *pAuxData; + VdbeFunc *pVdbeFunc; + if( iArg<0 ) goto failed; + + assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); + pVdbeFunc = pCtx->pVdbeFunc; + if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){ + int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0); + int nMalloc = sizeof(VdbeFunc) + sizeof(VdbeFunc::AuxData)*iArg; + pVdbeFunc = (VdbeFunc*)sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc); + if( !pVdbeFunc ){ + goto failed; + } + pCtx->pVdbeFunc = pVdbeFunc; + memset(&pVdbeFunc->apAux[nAux], 0, sizeof(VdbeFunc::AuxData)*(iArg+1-nAux)); + pVdbeFunc->nAux = iArg+1; + pVdbeFunc->pFunc = pCtx->pFunc; + } + + pAuxData = &pVdbeFunc->apAux[iArg]; + if( pAuxData->pAux && pAuxData->xDelete ){ + pAuxData->xDelete(pAuxData->pAux); + } + pAuxData->pAux = pAux; + pAuxData->xDelete = xDelete; + return; + +failed: + if( xDelete ){ + xDelete(pAux); + } +} + +/* +** Return the number of times the Step function of a aggregate has been +** called. +** +** This function is deprecated. Do not use it for new code. It is +** provide only to avoid breaking legacy code. New aggregate function +** implementations should keep their own counts within their aggregate +** context. +*/ +EXPORT_C int sqlite3_aggregate_count(sqlite3_context *p){ + assert( p && p->pFunc && p->pFunc->xStep ); + return p->pMem->n; +} + +/* +** Return the number of columns in the result set for the statement pStmt. +*/ +EXPORT_C int sqlite3_column_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + return pVm ? pVm->nResColumn : 0; +} + +/* +** Return the number of values available from the current row of the +** currently executing statement pStmt. +*/ +EXPORT_C int sqlite3_data_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( pVm==0 || !pVm->resOnStack ) return 0; + return pVm->nResColumn; +} + + +/* +** Check to see if column iCol of the given statement is valid. If +** it is, return a pointer to the Mem for the value of that column. +** If iCol is not valid, return a pointer to a Mem which has a value +** of NULL. +*/ +static Mem *columnMem(sqlite3_stmt *pStmt, int i){ + Vdbe *pVm; + int vals; + Mem *pOut; + + pVm = (Vdbe *)pStmt; + if( pVm && pVm->resOnStack && inResColumn && i>=0 ){ + sqlite3_mutex_enter(pVm->db->mutex); + vals = sqlite3_data_count(pStmt); + pOut = &pVm->pTos[(1-vals)+i]; + }else{ + static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL }; + if( pVm->db ){ + sqlite3_mutex_enter(pVm->db->mutex); + sqlite3Error(pVm->db, SQLITE_RANGE, 0); + } + pOut = (Mem*)&nullMem; + } + return pOut; +} + +/* +** This function is called after invoking an sqlite3_value_XXX function on a +** column value (i.e. a value returned by evaluating an SQL expression in the +** select list of a SELECT statement) that may cause a malloc() failure. If +** malloc() has failed, the threads mallocFailed flag is cleared and the result +** code of statement pStmt set to SQLITE_NOMEM. +** +** Specifically, this is called from within: +** +** sqlite3_column_int() +** sqlite3_column_int64() +** sqlite3_column_text() +** sqlite3_column_text16() +** sqlite3_column_real() +** sqlite3_column_bytes() +** sqlite3_column_bytes16() +** +** But not for sqlite3_column_blob(), which never calls malloc(). +*/ +static void columnMallocFailure(sqlite3_stmt *pStmt) +{ + /* If malloc() failed during an encoding conversion within an + ** sqlite3_column_XXX API, then set the return code of the statement to + ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR + ** and _finalize() will return NOMEM. + */ + Vdbe *p = (Vdbe *)pStmt; + if( p ){ + p->rc = sqlite3ApiExit(p->db, p->rc); + sqlite3_mutex_leave(p->db->mutex); + } +} + +/**************************** sqlite3_column_ ******************************* +** The following routines are used to access elements of the current row +** in the result set. +*/ +EXPORT_C const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ + const void *val; + val = sqlite3_value_blob( columnMem(pStmt,i) ); + /* Even though there is no encoding conversion, value_blob() might + ** need to call malloc() to expand the result of a zeroblob() + ** expression. + */ + columnMallocFailure(pStmt); + return val; +} +EXPORT_C int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +EXPORT_C int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +EXPORT_C double sqlite3_column_double(sqlite3_stmt *pStmt, int i){ + double val = sqlite3_value_double( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +EXPORT_C int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_int( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +EXPORT_C sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ + sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +EXPORT_C const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ + const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +EXPORT_C sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ + sqlite3_value *pOut = columnMem(pStmt, i); + columnMallocFailure(pStmt); + return pOut; +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ + const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return val; +} +#endif /* SQLITE_OMIT_UTF16 */ +EXPORT_C int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ + int iType = sqlite3_value_type( columnMem(pStmt,i) ); + columnMallocFailure(pStmt); + return iType; +} + +/* The following function is experimental and subject to change or +** removal */ +/*int sqlite3_column_numeric_type(sqlite3_stmt *pStmt, int i){ +** return sqlite3_value_numeric_type( columnMem(pStmt,i) ); +**} +*/ + +/* +** Convert the N-th element of pStmt->pColName[] into a string using +** xFunc() then return that string. If N is out of range, return 0. +** +** There are up to 5 names for each column. useType determines which +** name is returned. Here are the names: +** +** 0 The column name as it should be displayed for output +** 1 The datatype name for the column +** 2 The name of the database that the column derives from +** 3 The name of the table that the column derives from +** 4 The name of the table column that the result column derives from +** +** If the result is not a simple column reference (if it is an expression +** or a constant) then useTypes 2, 3, and 4 return NULL. +*/ +static const void *columnName( + sqlite3_stmt *pStmt, + int N, + const void *(*xFunc)(Mem*), + int useType +){ + const void *ret = 0; + Vdbe *p = (Vdbe *)pStmt; + int n; + + + if( p!=0 ){ + n = sqlite3_column_count(pStmt); + if( N=0 ){ + N += useType*n; + sqlite3_mutex_enter(p->db->mutex); + ret = xFunc(&p->aColName[N]); + + /* A malloc may have failed inside of the xFunc() call. If this + ** is the case, clear the mallocFailed flag and return NULL. + */ + if( p->db && p->db->mallocFailed ){ + p->db->mallocFailed = 0; + ret = 0; + } + sqlite3_mutex_leave(p->db->mutex); + } + } + return ret; +} + +/* +** Return the name of the Nth column of the result set returned by SQL +** statement pStmt. +*/ +EXPORT_C const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ + return (const char*)columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME); +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME); +} +#endif + +/* +** Return the column declaration type (if applicable) of the 'i'th column +** of the result set of SQL statement pStmt. +*/ +EXPORT_C const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ + return (const char*)columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE); +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +#ifdef SQLITE_ENABLE_COLUMN_METADATA +/* +** Return the name of the database from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unabiguous reference to a database column. +*/ +const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE); +} +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the name of the table from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unabiguous reference to a database column. +*/ +const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE); +} +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE); +} +#endif /* SQLITE_OMIT_UTF16 */ + +/* +** Return the name of the table column from which a result column derives. +** NULL is returned if the result column is an expression or constant or +** anything else which is not an unabiguous reference to a database column. +*/ +const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN); +} +#ifndef SQLITE_OMIT_UTF16 +const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ + return columnName( + pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN); +} +#endif /* SQLITE_OMIT_UTF16 */ +#endif /* SQLITE_ENABLE_COLUMN_METADATA */ + + +/******************************* sqlite3_bind_ *************************** +** +** Routines used to attach values to wildcards in a compiled SQL statement. +*/ +/* +** Unbind the value bound to variable i in virtual machine p. This is the +** the same as binding a NULL value to the column. If the "i" parameter is +** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. +** +** The error code stored in database p->db is overwritten with the return +** value in any case. +*/ +static int vdbeUnbind(Vdbe *p, int i){ + Mem *pVar; + if( p==0 || p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ + if( p ) sqlite3Error(p->db, SQLITE_MISUSE, 0); + return SQLITE_MISUSE; + } + if( i<1 || i>p->nVar ){ + sqlite3Error(p->db, SQLITE_RANGE, 0); + return SQLITE_RANGE; + } + i--; + pVar = &p->aVar[i]; + sqlite3VdbeMemRelease(pVar); + pVar->flags = MEM_Null; + sqlite3Error(p->db, SQLITE_OK, 0); + return SQLITE_OK; +} + +/* +** Bind a text or BLOB value. +*/ +static int bindText( + sqlite3_stmt *pStmt, /* The statement to bind against */ + int i, /* Index of the parameter to bind */ + const void *zData, /* Pointer to the data to be bound */ + int nData, /* Number of bytes of data to be bound */ + void (*xDel)(void*), /* Destructor for the data */ + int encoding /* Encoding for the data */ +){ + Vdbe *p = (Vdbe *)pStmt; + Mem *pVar; + int rc; + + if( p==0 ){ + return SQLITE_MISUSE; + } + sqlite3_mutex_enter(p->db->mutex); + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK && zData!=0 ){ + pVar = &p->aVar[i-1]; + rc = sqlite3VdbeMemSetStr(pVar, (const char*)zData, nData, encoding, xDel); + if( rc==SQLITE_OK && encoding!=0 ){ + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + } + sqlite3Error(p->db, rc, 0); + rc = sqlite3ApiExit(p->db, rc); + } + sqlite3_mutex_leave(p->db->mutex); + return rc; +} + + +/* +** Bind a blob value to an SQL statement variable. +*/ +EXPORT_C int sqlite3_bind_blob( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, 0); +} +EXPORT_C int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); + } + sqlite3_mutex_leave(p->db->mutex); + return rc; +} +EXPORT_C int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ + return sqlite3_bind_int64(p, i, (i64)iValue); +} +EXPORT_C int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); + } + sqlite3_mutex_leave(p->db->mutex); + return rc; +} +EXPORT_C int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ + int rc; + Vdbe *p = (Vdbe*)pStmt; + sqlite3_mutex_enter(p->db->mutex); + rc = vdbeUnbind(p, i); + sqlite3_mutex_leave(p->db->mutex); + return rc; +} +EXPORT_C int sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); +} +#ifndef SQLITE_OMIT_UTF16 +EXPORT_C int sqlite3_bind_text16( + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, + void (*xDel)(void*) +){ + return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); +} +#endif /* SQLITE_OMIT_UTF16 */ +EXPORT_C int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue); + } + sqlite3_mutex_leave(p->db->mutex); + return rc; +} +EXPORT_C int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ + int rc; + Vdbe *p = (Vdbe *)pStmt; + sqlite3_mutex_enter(p->db->mutex); + rc = vdbeUnbind(p, i); + if( rc==SQLITE_OK ){ + sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); + } + sqlite3_mutex_leave(p->db->mutex); + return rc; +} + +/* +** Return the number of wildcards that can be potentially bound to. +** This routine is added to support DBD::SQLite. +*/ +EXPORT_C int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ + Vdbe *p = (Vdbe*)pStmt; + return p ? p->nVar : 0; +} + +/* +** Create a mapping from variable numbers to variable names +** in the Vdbe.azVar[] array, if such a mapping does not already +** exist. +*/ +static void createVarMap(Vdbe *p){ + if( !p->okVar ){ + sqlite3_mutex_enter(p->db->mutex); + if( !p->okVar ){ + int j; + Op *pOp; + for(j=0, pOp=p->aOp; jnOp; j++, pOp++){ + if( pOp->opcode==OP_Variable ){ + assert( pOp->p1>0 && pOp->p1<=p->nVar ); + p->azVar[pOp->p1-1] = pOp->p3; + } + } + p->okVar = 1; + } + sqlite3_mutex_leave(p->db->mutex); + } +} + +/* +** Return the name of a wildcard parameter. Return NULL if the index +** is out of range or if the wildcard is unnamed. +** +** The result is always UTF-8. +*/ +EXPORT_C const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ + Vdbe *p = (Vdbe*)pStmt; + if( p==0 || i<1 || i>p->nVar ){ + return 0; + } + createVarMap(p); + return p->azVar[i-1]; +} + +/* +** Given a wildcard parameter name, return the index of the variable +** with that name. If there is no variable with the given name, +** return 0. +*/ +EXPORT_C int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ + Vdbe *p = (Vdbe*)pStmt; + int i; + if( p==0 ){ + return 0; + } + createVarMap(p); + if( zName ){ + for(i=0; inVar; i++){ + const char *z = p->azVar[i]; + if( z && strcmp(z,zName)==0 ){ + return i+1; + } + } + } + return 0; +} + +/* +** Transfer all bindings from the first statement over to the second. +** If the two statements contain a different number of bindings, then +** an SQLITE_ERROR is returned. +*/ +EXPORT_C int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ + Vdbe *pFrom = (Vdbe*)pFromStmt; + Vdbe *pTo = (Vdbe*)pToStmt; + int i, rc = SQLITE_OK; + if( (pFrom->magic!=VDBE_MAGIC_RUN && pFrom->magic!=VDBE_MAGIC_HALT) + || (pTo->magic!=VDBE_MAGIC_RUN && pTo->magic!=VDBE_MAGIC_HALT) + || pTo->db!=pFrom->db ){ + return SQLITE_MISUSE; + } + if( pFrom->nVar!=pTo->nVar ){ + return SQLITE_ERROR; + } + sqlite3_mutex_enter(pTo->db->mutex); + for(i=0; rc==SQLITE_OK && inVar; i++){ + sqlite3MallocDisallow(); + rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); + sqlite3MallocAllow(); + } + sqlite3_mutex_leave(pTo->db->mutex); + assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); + return rc; +} + +/* +** Return the sqlite3* database handle to which the prepared statement given +** in the argument belongs. This is the same database handle that was +** the first argument to the sqlite3_prepare() that was used to create +** the statement in the first place. +*/ +EXPORT_C sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ + return pStmt ? ((Vdbe*)pStmt)->db : 0; +}