📄 vdbeapi.c
字号:
/*** 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.*/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().*/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().*/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.*/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.*/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); }}int sqlite3_value_bytes(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF8);}int sqlite3_value_bytes16(sqlite3_value *pVal){ return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);}double sqlite3_value_double(sqlite3_value *pVal){ return sqlite3VdbeRealValue((Mem*)pVal);}int sqlite3_value_int(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal);}sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal);}const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);}#ifndef SQLITE_OMIT_UTF16const void *sqlite3_value_text16(sqlite3_value* pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);}const void *sqlite3_value_text16be(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16BE);}const void *sqlite3_value_text16le(sqlite3_value *pVal){ return sqlite3ValueText(pVal, SQLITE_UTF16LE);}#endif /* SQLITE_OMIT_UTF16 */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.*/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, z, n, 0, xDel);}void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetDouble(&pCtx->s, rVal);}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_UTF16void 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, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);}#endifvoid sqlite3_result_int(sqlite3_context *pCtx, int iVal){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);}void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetInt64(&pCtx->s, iVal);}void sqlite3_result_null(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemSetNull(&pCtx->s);}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_UTF16void 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, z, n, SQLITE_UTF16NATIVE, xDel);}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, z, n, SQLITE_UTF16BE, xDel);}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, z, n, SQLITE_UTF16LE, xDel);}#endif /* SQLITE_OMIT_UTF16 */void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); sqlite3VdbeMemCopy(&pCtx->s, pValue);}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. */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. */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)<SQLITE_ROW ){ /* This behavior occurs if sqlite3_prepare_v2() was used to build ** the prepared statement. Return error codes directly */ sqlite3Error(p->db, p->rc, 0); return p->rc; }else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -