⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdbeaux.c

📁 sqlite-source-2_8_16.zip 轻量级嵌入式数据库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
*/int sqliteVdbeList(  Vdbe *p                   /* The VDBE */){  sqlite *db = p->db;  int i;  int rc = SQLITE_OK;  static char *azColumnNames[] = {     "addr", "opcode", "p1",  "p2",  "p3",      "int",  "text",   "int", "int", "text",     0  };  assert( p->popStack==0 );  assert( p->explain );  p->azColName = azColumnNames;  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;    }    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].zShort, "ptr(%#lx)", (long)p->aOp[i].p3);      p->zArgv[4] = p->aStack[4].zShort;    }else{      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 rc;}/*** Prepare a virtual machine for execution.  This involves things such** 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().  */void sqliteVdbeMakeReady(  Vdbe *p,                       /* The VDBE */  int nVar,                      /* Number of '?' see in the SQL statement */  int isExplain                  /* True if the EXPLAIN keywords is present */){  int n;  assert( p!=0 );  assert( p->magic==VDBE_MAGIC_INIT );  /* Add a HALT instruction to the very end of the program.  */  if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){    sqliteVdbeAddOp(p, OP_Halt, 0, 0);  }  /* No instruction ever pushes more than a single element onto the  ** stack.  And the stack never grows on successive executions of the  ** same loop.  So the total number of instructions is an upper bound  ** on the maximum stack depth required.  **  ** Allocation all the stack space we will ever need.  */  if( p->aStack==0 ){    p->nVar = nVar;    assert( nVar>=0 );    n = isExplain ? 10 : p->nOp;    p->aStack = sqliteMalloc(      n*(sizeof(p->aStack[0]) + 2*sizeof(char*))     /* aStack and zArgv */        + p->nVar*(sizeof(char*)+sizeof(int)+1)    /* azVar, anVar, abVar */    );    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];  }  sqliteHashInit(&p->agg.hash, SQLITE_HASH_BINARY, 0);  p->agg.pSearch = 0;#ifdef MEMORY_DEBUG  if( sqliteOsFileExists("vdbe_trace") ){    p->trace = stdout;  }#endif  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->popStack =  0;  p->explain |= isExplain;  p->magic = VDBE_MAGIC_RUN;#ifdef VDBE_PROFILE  {    int i;    for(i=0; i<p->nOp; i++){      p->aOp[i].cnt = 0;      p->aOp[i].cycles = 0;    }  }#endif}/*** Remove any elements that remain on the sorter for the VDBE given.*/void sqliteVdbeSorterReset(Vdbe *p){  while( p->pSort ){    Sorter *pSorter = p->pSort;    p->pSort = pSorter->pNext;    sqliteFree(pSorter->zKey);    sqliteFree(pSorter->pData);    sqliteFree(pSorter);  }}/*** Reset an Agg structure.  Delete all its contents. **** For installable aggregate functions, if the step function has been** called, make sure the finalizer function has also been called.  The** finalizer might need to free memory that was allocated as part of its** private context.  If the finalizer has not been called yet, call it** now.*/void sqliteVdbeAggReset(Agg *pAgg){  int i;  HashElem *p;  for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){    AggElem *pElem = sqliteHashData(p);    assert( pAgg->apFunc!=0 );    for(i=0; i<pAgg->nMem; i++){      Mem *pMem = &pElem->aMem[i];      if( pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){        sqlite_func ctx;        ctx.pFunc = pAgg->apFunc[i];        ctx.s.flags = MEM_Null;        ctx.pAgg = pMem->z;        ctx.cnt = pMem->i;        ctx.isStep = 0;        ctx.isError = 0;        (*pAgg->apFunc[i]->xFinalize)(&ctx);        if( pMem->z!=0 && pMem->z!=pMem->zShort ){          sqliteFree(pMem->z);        }        if( ctx.s.flags & MEM_Dyn ){          sqliteFree(ctx.s.z);        }      }else if( pMem->flags & MEM_Dyn ){        sqliteFree(pMem->z);      }    }    sqliteFree(pElem);  }  sqliteHashClear(&pAgg->hash);  sqliteFree(pAgg->apFunc);  pAgg->apFunc = 0;  pAgg->pCurrent = 0;  pAgg->pSearch = 0;  pAgg->nMem = 0;}/*** Delete a keylist*/void sqliteVdbeKeylistFree(Keylist *p){  while( p ){    Keylist *pNext = p->pNext;    sqliteFree(p);    p = pNext;  }}/*** Close a cursor and release all the resources that cursor happens** to hold.*/void sqliteVdbeCleanupCursor(Cursor *pCx){  if( pCx->pCursor ){    sqliteBtreeCloseCursor(pCx->pCursor);  }  if( pCx->pBt ){    sqliteBtreeClose(pCx->pBt);  }  sqliteFree(pCx->pData);  memset(pCx, 0, sizeof(Cursor));}/*** Close all cursors*/static void closeAllCursors(Vdbe *p){  int i;  for(i=0; i<p->nCursor; i++){    sqliteVdbeCleanupCursor(&p->aCsr[i]);  }  sqliteFree(p->aCsr);  p->aCsr = 0;  p->nCursor = 0;}/*** Clean up the VM after execution.**** This routine will automatically close any cursors, lists, and/or** sorters that were left open.  It also deletes the values of** variables in the azVariable[] array.*/static void Cleanup(Vdbe *p){  int i;  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].flags & MEM_Dyn ){        sqliteFree(p->aMem[i].z);      }    }  }  sqliteFree(p->aMem);  p->aMem = 0;  p->nMem = 0;  if( p->pList ){    sqliteVdbeKeylistFree(p->pList);    p->pList = 0;  }  sqliteVdbeSorterReset(p);  if( p->pFile ){    if( p->pFile!=stdin ) fclose(p->pFile);    p->pFile = 0;  }  if( p->azField ){    sqliteFree(p->azField);    p->azField = 0;  }  p->nField = 0;  if( p->zLine ){    sqliteFree(p->zLine);    p->zLine = 0;  }  p->nLineAlloc = 0;  sqliteVdbeAggReset(&p->agg);  if( p->aSet ){    for(i=0; i<p->nSet; i++){      sqliteHashClear(&p->aSet[i].hash);    }  }  sqliteFree(p->aSet);  p->aSet = 0;  p->nSet = 0;  if( p->keylistStack ){    int ii;    for(ii = 0; ii < p->keylistStackDepth; ii++){      sqliteVdbeKeylistFree(p->keylistStack[ii]);    }    sqliteFree(p->keylistStack);    p->keylistStackDepth = 0;    p->keylistStack = 0;  }  sqliteFree(p->contextStack);  p->contextStack = 0;  sqliteFree(p->zErrMsg);  p->zErrMsg = 0;}/*** Clean up a VDBE after execution but do not delete the VDBE just yet.** Write any error messages into *pzErrMsg.  Return the result code.**** After this routine is run, the VDBE should be ready to be executed** again.*/int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){  sqlite *db = p->db;  int i;  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);    return SQLITE_MISUSE;  }  if( p->zErrMsg ){    if( pzErrMsg && *pzErrMsg==0 ){      *pzErrMsg = p->zErrMsg;    }else{      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 ){    switch( p->errorAction ){      case OE_Abort: {        if( !p->undoTransOnError ){          for(i=0; i<db->nDb; i++){            if( db->aDb[i].pBt ){              sqliteBtreeRollbackCkpt(db->aDb[i].pBt);            }          }          break;        }        /* Fall through to ROLLBACK */      }      case OE_Rollback: {        sqliteRollbackAll(db);        db->flags &= ~SQLITE_InTrans;        db->onError = OE_Default;        break;      }      default: {        if( p->undoTransOnError ){          sqliteRollbackAll(db);          db->flags &= ~SQLITE_InTrans;          db->onError = OE_Default;        }        break;      }    }    sqliteRollbackInternalChanges(db);  }  for(i=0; i<db->nDb; i++){    if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){      sqliteBtreeCommitCkpt(db->aDb[i].pBt);      db->aDb[i].inTrans = 1;    }  }  assert( p->pTos<&p->aStack[p->pc] || sqlite_malloc_failed==1 );#ifdef VDBE_PROFILE  {    FILE *out = fopen("vdbe_profile.out", "a");    if( out ){      int i;      fprintf(out, "---- ");      for(i=0; i<p->nOp; i++){        fprintf(out, "%02x", p->aOp[i].opcode);      }      fprintf(out, "\n");      for(i=0; i<p->nOp; i++){        fprintf(out, "%6d %10lld %8lld ",           p->aOp[i].cnt,           p->aOp[i].cycles,           p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0        );        sqliteVdbePrintOp(out, i, &p->aOp[i]);      }      fclose(out);    }  }#endif  p->magic = VDBE_MAGIC_INIT;  return p->rc;}/*** Clean up and delete a VDBE after execution.  Return an integer which is** the result code.  Write any error message text into *pzErrMsg.*/int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){  int rc;  sqlite *db;  if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);    return SQLITE_MISUSE;  }  db = p->db;  rc = sqliteVdbeReset(p, pzErrMsg);  sqliteVdbeDelete(p);  if( db->want_to_close && db->pVdbe==0 ){    sqlite_close(db);  }  if( rc==SQLITE_SCHEMA ){    sqliteResetInternalSchema(db, 0);  }  return rc;}/*** Set the values of all variables.  Variable $1 in the original SQL will** be the string azValue[0].  $2 will have the value azValue[1].  And** so forth.  If a value is out of range (for example $3 when nValue==2)** then its value will be NULL.**** This routine overrides any prior call.*/int sqlite_bind(sqlite_vm *pVm, int i, const char *zVal, int len, int copy){  Vdbe *p = (Vdbe*)pVm;  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){    return SQLITE_MISUSE;  }  if( i<1 || i>p->nVar ){    return SQLITE_RANGE;  }  i--;  if( p->abVar[i] ){    sqliteFree(p->azVar[i]);  }  if( zVal==0 ){    copy = 0;    len = 0;  }  if( len<0 ){    len = strlen(zVal)+1;  }  if( copy ){    p->azVar[i] = sqliteMalloc( len );    if( p->azVar[i] ) memcpy(p->azVar[i], zVal, len);  }else{    p->azVar[i] = (char*)zVal;  }  p->abVar[i] = copy;  p->anVar[i] = len;  return SQLITE_OK;}/*** Delete an entire VDBE.*/void sqliteVdbeDelete(Vdbe *p){  int i;  if( p==0 ) return;  Cleanup(p);  if( p->pPrev ){    p->pPrev->pNext = p->pNext;  }else{    assert( p->db->pVdbe==p );    p->db->pVdbe = p->pNext;  }  if( p->pNext ){    p->pNext->pPrev = p->pPrev;  }  p->pPrev = p->pNext = 0;  if( p->nOpAlloc==0 ){    p->aOp = 0;    p->nOp = 0;  }  for(i=0; i<p->nOp; i++){    if( p->aOp[i].p3type==P3_DYNAMIC ){      sqliteFree(p->aOp[i].p3);    }  }  for(i=0; i<p->nVar; i++){    if( p->abVar[i] ) sqliteFree(p->azVar[i]);  }  sqliteFree(p->aOp);  sqliteFree(p->aLabel);  sqliteFree(p->aStack);  p->magic = VDBE_MAGIC_DEAD;  sqliteFree(p);}/*** Convert an integer in between the native integer format and** the bigEndian format used as the record number for tables.**** The bigEndian format (most significant byte first) is used for** record numbers so that records will sort into the correct order** even though memcmp() is used to compare the keys.  On machines** whose native integer format is little endian (ex: i486) the** order of bytes is reversed.  On native big-endian machines** (ex: Alpha, Sparc, Motorola) the byte order is the same.**** This function is its own inverse.  In other words****         X == byteSwap(byteSwap(X))*/int sqliteVdbeByteSwap(int x){  union {     char zBuf[sizeof(int)];     int i;  } ux;  ux.zBuf[3] = x&0xff;  ux.zBuf[2] = (x>>8)&0xff;  ux.zBuf[1] = (x>>16)&0xff;  ux.zBuf[0] = (x>>24)&0xff;  return ux.i;}/*** If a MoveTo operation is pending on the given cursor, then do that** MoveTo now.  Return an error code.  If no MoveTo is pending, this** routine does nothing and returns SQLITE_OK.*/int sqliteVdbeCursorMoveto(Cursor *p){  if( p->deferredMoveto ){    int res;    extern int sqlite_search_count;    sqliteBtreeMoveto(p->pCursor, (char*)&p->movetoTarget, sizeof(int), &res);    p->lastRecno = keyToInt(p->movetoTarget);    p->recnoIsValid = res==0;    if( res<0 ){      sqliteBtreeNext(p->pCursor, &res);    }    sqlite_search_count++;    p->deferredMoveto = 0;  }  return SQLITE_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -