?? 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"
#include "os.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;
}
/**************************** 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) ){
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_UTF16
const 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_value_numeric_type() defined in vdbe.c */
/**************************** 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 );
sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
}
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
}
void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
pCtx->isError = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
pCtx->isError = 1;
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
}
#endif
void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
}
void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
}
void sqlite3_result_null(sqlite3_context *pCtx){
sqlite3VdbeMemSetNull(&pCtx->s);
}
void sqlite3_result_text(
sqlite3_context *pCtx,
const char *z,
int n,
void (*xDel)(void *)
){
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
}
#ifndef SQLITE_OMIT_UTF16
void sqlite3_result_text16(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
}
void sqlite3_result_text16be(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
}
void sqlite3_result_text16le(
sqlite3_context *pCtx,
const void *z,
int n,
void (*xDel)(void *)
){
sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
sqlite3VdbeMemCopy(&pCtx->s, pValue);
}
/*
** Execute the statement pStmt, either until a row of data is ready, the
** statement is completely executed or an error occurs.
*/
int sqlite3_step(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe*)pStmt;
sqlite3 *db;
int rc;
/* Assert that malloc() has not failed */
assert( !sqlite3MallocFailed() );
if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_MISUSE;
}
if( p->aborted ){
return SQLITE_ABORT;
}
if( p->pc<=0 && p->expired ){
if( p->rc==SQLITE_OK ){
p->rc = SQLITE_SCHEMA;
}
return SQLITE_ERROR;
}
db = p->db;
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(&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(&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);
assert( (rc&0xff)==rc );
return rc;
}
/*
** Extract the user data from a sqlite3_context structure and return a
** pointer to it.
*/
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(
"unable to use function %s in the requested context", zName);
sqlite3_result_error(context, zErr, -1);
sqliteFree(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.
*/
void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
Mem *pMem = p->pMem;
assert( p && p->pFunc && p->pFunc->xStep );
if( (pMem->flags & MEM_Agg)==0 ){
if( nByte==0 ){
assert( pMem->flags==MEM_Null );
pMem->z = 0;
}else{
pMem->flags = MEM_Agg;
pMem->xDel = sqlite3FreeX;
*(FuncDef**)&pMem->i = p->pFunc;
if( nByte<=NBFS ){
pMem->z = pMem->zShort;
memset(pMem->z, 0, nByte);
}else{
pMem->z = sqliteMalloc( nByte );
}
}
}
return (void*)pMem->z;
}
/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
VdbeFunc *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.
*/
void sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
void (*xDelete)(void*)
){
struct AuxData *pAuxData;
VdbeFunc *pVdbeFunc;
if( iArg<0 ) return;
pVdbeFunc = pCtx->pVdbeFunc;
if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
pVdbeFunc = sqliteRealloc(pVdbeFunc, nMalloc);
if( !pVdbeFunc ) return;
pCtx->pVdbeFunc = pVdbeFunc;
memset(&pVdbeFunc->apAux[pVdbeFunc->nAux], 0,
sizeof(struct AuxData)*(iArg+1-pVdbeFunc->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 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.
*/
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.
*/
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.
*/
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 = (Vdbe *)pStmt;
int vals = sqlite3_data_count(pStmt);
if( i>=vals || i<0 ){
static const Mem nullMem = {0, 0.0, "", 0, MEM_Null, MEM_Null };
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
return (Mem*)&nullMem;
}
return &pVm->pTos[(1-vals)+i];
}
/*
** 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.
**
** Specificly, this is called from within:
**
** sqlite3_column_int()
** sqlite3_column_int64()
** sqlite3_column_text()
** sqlite3_column_text16()
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -