summaryrefslogtreecommitdiff
path: root/ext/sqlite/libsqlite/src/vdbeaux.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/sqlite/libsqlite/src/vdbeaux.c')
-rw-r--r--ext/sqlite/libsqlite/src/vdbeaux.c249
1 files changed, 134 insertions, 115 deletions
diff --git a/ext/sqlite/libsqlite/src/vdbeaux.c b/ext/sqlite/libsqlite/src/vdbeaux.c
index 087128cbbc..c206bad4ab 100644
--- a/ext/sqlite/libsqlite/src/vdbeaux.c
+++ b/ext/sqlite/libsqlite/src/vdbeaux.c
@@ -73,6 +73,7 @@ void sqliteVdbeTrace(Vdbe *p, FILE *trace){
*/
int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
int i;
+ VdbeOp *pOp;
i = p->nOp;
p->nOp++;
@@ -89,14 +90,15 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
p->aOp = aNew;
memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
}
- p->aOp[i].opcode = op;
- p->aOp[i].p1 = p1;
+ pOp = &p->aOp[i];
+ pOp->opcode = op;
+ pOp->p1 = p1;
if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
p2 = p->aLabel[-1-p2];
}
- p->aOp[i].p2 = p2;
- p->aOp[i].p3 = 0;
- p->aOp[i].p3type = P3_NOTUSED;
+ pOp->p2 = p2;
+ pOp->p3 = 0;
+ pOp->p3type = P3_NOTUSED;
#ifndef NDEBUG
if( sqlite_vdbe_addop_trace ) sqliteVdbePrintOp(0, i, &p->aOp[i]);
#endif
@@ -104,6 +106,35 @@ int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
}
/*
+** Add an opcode that includes the p3 value.
+*/
+int sqliteVdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3, int p3type){
+ int addr = sqliteVdbeAddOp(p, op, p1, p2);
+ sqliteVdbeChangeP3(p, addr, zP3, p3type);
+ return addr;
+}
+
+/*
+** Add multiple opcodes. The list is terminated by an opcode of 0.
+*/
+int sqliteVdbeCode(Vdbe *p, ...){
+ int addr;
+ va_list ap;
+ int opcode, p1, p2;
+ va_start(ap, p);
+ addr = p->nOp;
+ while( (opcode = va_arg(ap,int))!=0 ){
+ p1 = va_arg(ap,int);
+ p2 = va_arg(ap,int);
+ sqliteVdbeAddOp(p, opcode, p1, p2);
+ }
+ va_end(ap);
+ return addr;
+}
+
+
+
+/*
** Create a new symbolic label for an instruction that has yet to be
** coded. The symbolic label is really just a negative number. The
** label can be used as the P2 value of an operation. Later, when
@@ -167,7 +198,7 @@ int sqliteVdbeCurrentAddr(Vdbe *p){
** Add a whole list of operations to the operation stack. Return the
** address of the first operation added.
*/
-int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
+int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->nOp + nOp >= p->nOpAlloc ){
@@ -185,11 +216,15 @@ int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOp const *aOp){
addr = p->nOp;
if( nOp>0 ){
int i;
- for(i=0; i<nOp; i++){
- int p2 = aOp[i].p2;
- p->aOp[i+addr] = aOp[i];
- if( p2<0 ) p->aOp[i+addr].p2 = addr + ADDR(p2);
- p->aOp[i+addr].p3type = aOp[i].p3 ? P3_STATIC : P3_NOTUSED;
+ VdbeOpList const *pIn = aOp;
+ for(i=0; i<nOp; i++, pIn++){
+ int p2 = pIn->p2;
+ VdbeOp *pOut = &p->aOp[i+addr];
+ pOut->opcode = pIn->opcode;
+ pOut->p1 = pIn->p1;
+ pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
+ pOut->p3 = pIn->p3;
+ pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
#ifndef NDEBUG
if( sqlite_vdbe_addop_trace ){
sqliteVdbePrintOp(0, i+addr, &p->aOp[i+addr]);
@@ -280,7 +315,11 @@ void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
void sqliteVdbeDequoteP3(Vdbe *p, int addr){
Op *pOp;
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
+ if( p->aOp==0 ) return;
+ if( addr<0 || addr>=p->nOp ){
+ addr = p->nOp - 1;
+ if( addr<0 ) return;
+ }
pOp = &p->aOp[addr];
if( pOp->p3==0 || pOp->p3[0]==0 ) return;
if( pOp->p3type==P3_POINTER ) return;
@@ -371,48 +410,48 @@ VdbeOp *sqliteVdbeGetOp(Vdbe *p, int addr){
*/
char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
assert( !p->isStep );
- if( p->s.flags & STK_Dyn ){
- sqliteFree(p->z);
+ if( p->s.flags & MEM_Dyn ){
+ sqliteFree(p->s.z);
}
if( zResult==0 ){
- p->s.flags = STK_Null;
+ p->s.flags = MEM_Null;
n = 0;
- p->z = 0;
+ p->s.z = 0;
p->s.n = 0;
}else{
if( n<0 ) n = strlen(zResult);
if( n<NBFS-1 ){
- memcpy(p->s.z, zResult, n);
- p->s.z[n] = 0;
- p->s.flags = STK_Str;
- p->z = p->s.z;
+ memcpy(p->s.zShort, zResult, n);
+ p->s.zShort[n] = 0;
+ p->s.flags = MEM_Str | MEM_Short;
+ p->s.z = p->s.zShort;
}else{
- p->z = sqliteMallocRaw( n+1 );
- if( p->z ){
- memcpy(p->z, zResult, n);
- p->z[n] = 0;
+ p->s.z = sqliteMallocRaw( n+1 );
+ if( p->s.z ){
+ memcpy(p->s.z, zResult, n);
+ p->s.z[n] = 0;
}
- p->s.flags = STK_Str | STK_Dyn;
+ p->s.flags = MEM_Str | MEM_Dyn;
}
p->s.n = n+1;
}
- return p->z;
+ return p->s.z;
}
void sqlite_set_result_int(sqlite_func *p, int iResult){
assert( !p->isStep );
- if( p->s.flags & STK_Dyn ){
- sqliteFree(p->z);
+ if( p->s.flags & MEM_Dyn ){
+ sqliteFree(p->s.z);
}
p->s.i = iResult;
- p->s.flags = STK_Int;
+ p->s.flags = MEM_Int;
}
void sqlite_set_result_double(sqlite_func *p, double rResult){
assert( !p->isStep );
- if( p->s.flags & STK_Dyn ){
- sqliteFree(p->z);
+ if( p->s.flags & MEM_Dyn ){
+ sqliteFree(p->s.z);
}
p->s.r = rResult;
- p->s.flags = STK_Real;
+ p->s.flags = MEM_Real;
}
void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
assert( !p->isStep );
@@ -442,7 +481,8 @@ void *sqlite_aggregate_context(sqlite_func *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
if( p->pAgg==0 ){
if( nByte<=NBFS ){
- p->pAgg = (void*)p->z;
+ p->pAgg = (void*)p->s.z;
+ memset(p->pAgg, 0, nByte);
}else{
p->pAgg = sqliteMalloc( nByte );
}
@@ -495,6 +535,7 @@ int sqliteVdbeList(
){
sqlite *db = p->db;
int i;
+ int rc = SQLITE_OK;
static char *azColumnNames[] = {
"addr", "opcode", "p1", "p2", "p3",
"int", "text", "int", "int", "text",
@@ -504,48 +545,39 @@ int sqliteVdbeList(
assert( p->popStack==0 );
assert( p->explain );
p->azColName = azColumnNames;
- p->azResColumn = p->zStack;
- for(i=0; i<5; i++) p->zStack[i] = p->aStack[i].z;
- p->rc = SQLITE_OK;
- for(i=p->pc; p->rc==SQLITE_OK && i<p->nOp; i++){
- if( db->flags & SQLITE_Interrupt ){
- db->flags &= ~SQLITE_Interrupt;
- if( db->magic!=SQLITE_MAGIC_BUSY ){
- p->rc = SQLITE_MISUSE;
- }else{
- p->rc = SQLITE_INTERRUPT;
- }
- sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
- break;
+ p->azResColumn = p->zArgv;
+ for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort;
+ i = p->pc;
+ if( i>=p->nOp ){
+ p->rc = SQLITE_OK;
+ rc = SQLITE_DONE;
+ }else if( db->flags & SQLITE_Interrupt ){
+ db->flags &= ~SQLITE_Interrupt;
+ if( db->magic!=SQLITE_MAGIC_BUSY ){
+ p->rc = SQLITE_MISUSE;
+ }else{
+ p->rc = SQLITE_INTERRUPT;
}
- sprintf(p->zStack[0],"%d",i);
- sprintf(p->zStack[2],"%d", p->aOp[i].p1);
- sprintf(p->zStack[3],"%d", p->aOp[i].p2);
+ rc = SQLITE_ERROR;
+ sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
+ }else{
+ sprintf(p->zArgv[0],"%d",i);
+ sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
+ sprintf(p->zArgv[3],"%d", p->aOp[i].p2);
if( p->aOp[i].p3type==P3_POINTER ){
- sprintf(p->aStack[4].z, "ptr(%#lx)", (long)p->aOp[i].p3);
- p->zStack[4] = p->aStack[4].z;
+ sprintf(p->aStack[4].zShort, "ptr(%#lx)", (long)p->aOp[i].p3);
+ p->zArgv[4] = p->aStack[4].zShort;
}else{
- p->zStack[4] = p->aOp[i].p3;
- }
- p->zStack[1] = sqliteOpcodeNames[p->aOp[i].opcode];
- if( p->xCallback==0 ){
- p->pc = i+1;
- p->azResColumn = p->zStack;
- p->nResColumn = 5;
- return SQLITE_ROW;
- }
- if( sqliteSafetyOff(db) ){
- p->rc = SQLITE_MISUSE;
- break;
- }
- if( p->xCallback(p->pCbArg, 5, p->zStack, p->azColName) ){
- p->rc = SQLITE_ABORT;
- }
- if( sqliteSafetyOn(db) ){
- p->rc = SQLITE_MISUSE;
+ p->zArgv[4] = p->aOp[i].p3;
}
+ p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode];
+ p->pc = i+1;
+ p->azResColumn = p->zArgv;
+ p->nResColumn = 5;
+ p->rc = SQLITE_OK;
+ rc = SQLITE_ROW;
}
- return p->rc==SQLITE_OK ? SQLITE_DONE : SQLITE_ERROR;
+ return rc;
}
/*
@@ -553,20 +585,10 @@ int sqliteVdbeList(
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqliteVdbeExec().
-**
-** The behavior of sqliteVdbeExec() is influenced by the parameters to
-** this routine. If xCallback is NULL, then sqliteVdbeExec() will return
-** with SQLITE_ROW whenever there is a row of the result set ready
-** to be delivered. p->azResColumn will point to the row and
-** p->nResColumn gives the number of columns in the row. If xCallback
-** is not NULL, then the xCallback() routine is invoked to process each
-** row in the result set.
*/
void sqliteVdbeMakeReady(
Vdbe *p, /* The VDBE */
int nVar, /* Number of '?' see in the SQL statement */
- sqlite_callback xCallback, /* Result callback */
- void *pCallbackArg, /* 1st argument to xCallback() */
int isExplain /* True if the EXPLAIN keywords is present */
){
int n;
@@ -592,11 +614,11 @@ void sqliteVdbeMakeReady(
assert( nVar>=0 );
n = isExplain ? 10 : p->nOp;
p->aStack = sqliteMalloc(
- n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) /* aStack and zStack */
- + p->nVar*(sizeof(char*)+sizeof(int)+1) /* azVar, anVar, abVar */
+ n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) /* aStack and zArgv */
+ + p->nVar*(sizeof(char*)+sizeof(int)+1) /* azVar, anVar, abVar */
);
- p->zStack = (char**)&p->aStack[n];
- p->azColName = (char**)&p->zStack[n];
+ p->zArgv = (char**)&p->aStack[n];
+ p->azColName = (char**)&p->zArgv[n];
p->azVar = (char**)&p->azColName[n];
p->anVar = (int*)&p->azVar[p->nVar];
p->abVar = (u8*)&p->anVar[p->nVar];
@@ -609,15 +631,13 @@ void sqliteVdbeMakeReady(
p->trace = stdout;
}
#endif
- p->tos = -1;
+ p->pTos = &p->aStack[-1];
p->pc = 0;
p->rc = SQLITE_OK;
p->uniqueCnt = 0;
p->returnDepth = 0;
p->errorAction = OE_Abort;
p->undoTransOnError = 0;
- p->xCallback = xCallback;
- p->pCbArg = pCallbackArg;
p->popStack = 0;
p->explain |= isExplain;
p->magic = VDBE_MAGIC_RUN;
@@ -647,25 +667,6 @@ void sqliteVdbeSorterReset(Vdbe *p){
}
/*
-** Pop the stack N times. Free any memory associated with the
-** popped stack elements.
-*/
-void sqliteVdbePopStack(Vdbe *p, int N){
- assert( N>=0 );
- if( p->zStack==0 ) return;
- assert( p->aStack || sqlite_malloc_failed );
- if( p->aStack==0 ) return;
- while( N-- > 0 ){
- if( p->aStack[p->tos].flags & STK_Dyn ){
- sqliteFree(p->zStack[p->tos]);
- }
- p->aStack[p->tos].flags = 0;
- p->zStack[p->tos] = 0;
- p->tos--;
- }
-}
-
-/*
** Reset an Agg structure. Delete all its contents.
**
** For installable aggregate functions, if the step function has been
@@ -682,20 +683,22 @@ void sqliteVdbeAggReset(Agg *pAgg){
assert( pAgg->apFunc!=0 );
for(i=0; i<pAgg->nMem; i++){
Mem *pMem = &pElem->aMem[i];
- if( pAgg->apFunc[i] && (pMem->s.flags & STK_AggCtx)!=0 ){
+ if( pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
sqlite_func ctx;
ctx.pFunc = pAgg->apFunc[i];
- ctx.s.flags = STK_Null;
- ctx.z = 0;
+ ctx.s.flags = MEM_Null;
ctx.pAgg = pMem->z;
- ctx.cnt = pMem->s.i;
+ ctx.cnt = pMem->i;
ctx.isStep = 0;
ctx.isError = 0;
(*pAgg->apFunc[i]->xFinalize)(&ctx);
- if( pMem->z!=0 && pMem->z!=pMem->s.z ){
+ if( pMem->z!=0 && pMem->z!=pMem->zShort ){
sqliteFree(pMem->z);
}
- }else if( pMem->s.flags & STK_Dyn ){
+ if( ctx.s.flags & MEM_Dyn ){
+ sqliteFree(ctx.s.z);
+ }
+ }else if( pMem->flags & MEM_Dyn ){
sqliteFree(pMem->z);
}
}
@@ -757,11 +760,20 @@ static void closeAllCursors(Vdbe *p){
*/
static void Cleanup(Vdbe *p){
int i;
- sqliteVdbePopStack(p, p->tos+1);
+ if( p->aStack ){
+ Mem *pTos = p->pTos;
+ while( pTos>=p->aStack ){
+ if( pTos->flags & MEM_Dyn ){
+ sqliteFree(pTos->z);
+ }
+ pTos--;
+ }
+ p->pTos = pTos;
+ }
closeAllCursors(p);
if( p->aMem ){
for(i=0; i<p->nMem; i++){
- if( p->aMem[i].s.flags & STK_Dyn ){
+ if( p->aMem[i].flags & MEM_Dyn ){
sqliteFree(p->aMem[i].z);
}
}
@@ -806,6 +818,8 @@ static void Cleanup(Vdbe *p){
p->keylistStackDepth = 0;
p->keylistStack = 0;
}
+ sqliteFree(p->contextStack);
+ p->contextStack = 0;
sqliteFree(p->zErrMsg);
p->zErrMsg = 0;
}
@@ -832,6 +846,8 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
sqliteFree(p->zErrMsg);
}
p->zErrMsg = 0;
+ }else if( p->rc ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(p->rc), (char*)0);
}
Cleanup(p);
if( p->rc!=SQLITE_OK ){
@@ -870,7 +886,7 @@ int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
db->aDb[i].inTrans = 1;
}
}
- assert( p->tos<p->pc || sqlite_malloc_failed==1 );
+ assert( p->pTos<&p->aStack[p->pc] || sqlite_malloc_failed==1 );
#ifdef VDBE_PROFILE
{
FILE *out = fopen("vdbe_profile.out", "a");
@@ -915,6 +931,9 @@ int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
if( db->want_to_close && db->pVdbe==0 ){
sqlite_close(db);
}
+ if( rc==SQLITE_SCHEMA ){
+ sqliteResetInternalSchema(db, 0);
+ }
return rc;
}