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

📄 vdbeaux.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5);   /* P5 */      pMem->type = SQLITE_TEXT;      pMem->enc = SQLITE_UTF8;      pMem++;  #ifdef SQLITE_DEBUG      if( pOp->zComment ){        pMem->flags = MEM_Str|MEM_Term;        pMem->z = pOp->zComment;        pMem->n = strlen(pMem->z);        pMem->enc = SQLITE_UTF8;      }else#endif      {        pMem->flags = MEM_Null;                       /* Comment */        pMem->type = SQLITE_NULL;      }    }    p->nResColumn = 8 - 5*(p->explain-1);    p->rc = SQLITE_OK;    rc = SQLITE_ROW;  }  return rc;}#endif /* SQLITE_OMIT_EXPLAIN */#ifdef SQLITE_DEBUG/*** Print the SQL that was used to generate a VDBE program.*/void sqlite3VdbePrintSql(Vdbe *p){  int nOp = p->nOp;  VdbeOp *pOp;  if( nOp<1 ) return;  pOp = &p->aOp[0];  if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){    const char *z = pOp->p4.z;    while( isspace(*(u8*)z) ) z++;    printf("SQL: [%s]\n", z);  }}#endif#if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)/*** Print an IOTRACE message showing SQL content.*/void sqlite3VdbeIOTraceSql(Vdbe *p){  int nOp = p->nOp;  VdbeOp *pOp;  if( sqlite3IoTrace==0 ) return;  if( nOp<1 ) return;  pOp = &p->aOp[0];  if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){    int i, j;    char z[1000];    sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);    for(i=0; isspace((unsigned char)z[i]); i++){}    for(j=0; z[i]; i++){      if( isspace((unsigned char)z[i]) ){        if( z[i-1]!=' ' ){          z[j++] = ' ';        }      }else{        z[j++] = z[i];      }    }    z[j] = 0;    sqlite3IoTrace("SQL %s\n", z);  }}#endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE *//*** 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 sqlite3VdbeExec().  **** This is the only way to move a VDBE from VDBE_MAGIC_INIT to** VDBE_MAGIC_RUN.*/void sqlite3VdbeMakeReady(  Vdbe *p,                       /* The VDBE */  int nVar,                      /* Number of '?' see in the SQL statement */  int nMem,                      /* Number of memory cells to allocate */  int nCursor,                   /* Number of cursors to allocate */  int isExplain                  /* True if the EXPLAIN keywords is present */){  int n;  sqlite3 *db = p->db;  assert( p!=0 );  assert( p->magic==VDBE_MAGIC_INIT );  /* There should be at least one opcode.  */  assert( p->nOp>0 );  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. This   * is because the call to resizeOpArray() below may shrink the   * p->aOp[] array to save memory if called when in VDBE_MAGIC_RUN    * state.   */  p->magic = VDBE_MAGIC_RUN;  /* For each cursor required, also allocate a memory cell. Memory  ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by  ** the vdbe program. Instead they are used to allocate space for  ** Cursor/BtCursor structures. The blob of memory associated with   ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)  ** stores the blob of memory associated with cursor 1, etc.  **  ** See also: allocateCursor().  */  nMem += nCursor;  /*  ** Allocation space for registers.  */  if( p->aMem==0 ){    int nArg;       /* Maximum number of args passed to a user function. */    resolveP2Values(p, &nArg);    /*resizeOpArray(p, p->nOp);*/    assert( nVar>=0 );    if( isExplain && nMem<10 ){      p->nMem = nMem = 10;    }    p->aMem = sqlite3DbMallocZero(db,        nMem*sizeof(Mem)               /* aMem */      + nVar*sizeof(Mem)               /* aVar */      + nArg*sizeof(Mem*)              /* apArg */      + nVar*sizeof(char*)             /* azVar */      + nCursor*sizeof(Cursor*) + 1    /* apCsr */    );    if( !db->mallocFailed ){      p->aMem--;             /* aMem[] goes from 1..nMem */      p->nMem = nMem;        /*       not from 0..nMem-1 */      p->aVar = &p->aMem[nMem+1];      p->nVar = nVar;      p->okVar = 0;      p->apArg = (Mem**)&p->aVar[nVar];      p->azVar = (char**)&p->apArg[nArg];      p->apCsr = (Cursor**)&p->azVar[nVar];      p->nCursor = nCursor;      for(n=0; n<nVar; n++){        p->aVar[n].flags = MEM_Null;        p->aVar[n].db = db;      }      for(n=1; n<=nMem; n++){        p->aMem[n].flags = MEM_Null;        p->aMem[n].db = db;      }    }  }#ifdef SQLITE_DEBUG  for(n=1; n<p->nMem; n++){    assert( p->aMem[n].db==db );  }#endif  p->pc = -1;  p->rc = SQLITE_OK;  p->uniqueCnt = 0;  p->errorAction = OE_Abort;  p->explain |= isExplain;  p->magic = VDBE_MAGIC_RUN;  p->nChange = 0;  p->cacheCtr = 1;  p->minWriteFileFormat = 255;  p->openedStatement = 0;#ifdef VDBE_PROFILE  {    int i;    for(i=0; i<p->nOp; i++){      p->aOp[i].cnt = 0;      p->aOp[i].cycles = 0;    }  }#endif}/*** Close a VDBE cursor and release all the resources that cursor ** happens to hold.*/void sqlite3VdbeFreeCursor(Vdbe *p, Cursor *pCx){  if( pCx==0 ){    return;  }  if( pCx->pBt ){    sqlite3BtreeClose(pCx->pBt);    /* The pCx->pCursor will be close automatically, if it exists, by    ** the call above. */  }else if( pCx->pCursor ){    sqlite3BtreeCloseCursor(pCx->pCursor);  }#ifndef SQLITE_OMIT_VIRTUALTABLE  if( pCx->pVtabCursor ){    sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;    const sqlite3_module *pModule = pCx->pModule;    p->inVtabMethod = 1;    (void)sqlite3SafetyOff(p->db);    pModule->xClose(pVtabCursor);    (void)sqlite3SafetyOn(p->db);    p->inVtabMethod = 0;  }#endif  if( !pCx->ephemPseudoTable ){    sqlite3DbFree(p->db, pCx->pData);  }}/*** Close all cursors except for VTab cursors that are currently** in use.*/static void closeAllCursorsExceptActiveVtabs(Vdbe *p){  int i;  if( p->apCsr==0 ) return;  for(i=0; i<p->nCursor; i++){    Cursor *pC = p->apCsr[i];    if( pC && (!p->inVtabMethod || !pC->pVtabCursor) ){      sqlite3VdbeFreeCursor(p, pC);      p->apCsr[i] = 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 aVar[] array.*/static void Cleanup(Vdbe *p){  int i;  sqlite3 *db = p->db;  closeAllCursorsExceptActiveVtabs(p);  for(i=1; i<=p->nMem; i++){    MemSetTypeFlag(&p->aMem[i], MEM_Null);  }  releaseMemArray(&p->aMem[1], p->nMem);  sqlite3VdbeFifoClear(&p->sFifo);  if( p->contextStack ){    for(i=0; i<p->contextStackTop; i++){      sqlite3VdbeFifoClear(&p->contextStack[i].sFifo);    }    sqlite3DbFree(db, p->contextStack);  }  p->contextStack = 0;  p->contextStackDepth = 0;  p->contextStackTop = 0;  sqlite3DbFree(db, p->zErrMsg);  p->zErrMsg = 0;  p->pResultSet = 0;}/*** Set the number of result columns that will be returned by this SQL** statement. This is now set at compile time, rather than during** execution of the vdbe program so that sqlite3_column_count() can** be called on an SQL statement before sqlite3_step().*/void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){  Mem *pColName;  int n;  sqlite3 *db = p->db;  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);  sqlite3DbFree(db, p->aColName);  n = nResColumn*COLNAME_N;  p->nResColumn = nResColumn;  p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n );  if( p->aColName==0 ) return;  while( n-- > 0 ){    pColName->flags = MEM_Null;    pColName->db = p->db;    pColName++;  }}/*** Set the name of the idx'th column to be returned by the SQL statement.** zName must be a pointer to a nul terminated string.**** This call must be made after a call to sqlite3VdbeSetNumCols().**** If N==P4_STATIC  it means that zName is a pointer to a constant static** string and we can just copy the pointer. If it is P4_DYNAMIC, then ** the string is freed using sqlite3DbFree(db, ) when the vdbe is finished with** it. Otherwise, N bytes of zName are copied.*/int sqlite3VdbeSetColName(Vdbe *p, int idx, int var, const char *zName, int N){  int rc;  Mem *pColName;  assert( idx<p->nResColumn );  assert( var<COLNAME_N );  if( p->db->mallocFailed ) return SQLITE_NOMEM;  assert( p->aColName!=0 );  pColName = &(p->aColName[idx+var*p->nResColumn]);  if( N==P4_DYNAMIC || N==P4_STATIC ){    rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, SQLITE_STATIC);  }else{    rc = sqlite3VdbeMemSetStr(pColName, zName, N, SQLITE_UTF8,SQLITE_TRANSIENT);  }  if( rc==SQLITE_OK && N==P4_DYNAMIC ){    pColName->flags &= (~MEM_Static);    pColName->zMalloc = pColName->z;  }  return rc;}/*** A read or write transaction may or may not be active on database handle** db. If a transaction is active, commit it. If there is a** write-transaction spanning more than one database file, this routine** takes care of the master journal trickery.*/static int vdbeCommit(sqlite3 *db, Vdbe *p){  int i;  int nTrans = 0;  /* Number of databases with an active write-transaction */  int rc = SQLITE_OK;  int needXcommit = 0;  /* Before doing anything else, call the xSync() callback for any  ** virtual module tables written in this transaction. This has to  ** be done before determining whether a master journal file is   ** required, as an xSync() callback may add an attached database  ** to the transaction.  */  rc = sqlite3VtabSync(db, &p->zErrMsg);  if( rc!=SQLITE_OK ){    return rc;  }  /* This loop determines (a) if the commit hook should be invoked and  ** (b) how many database files have open write transactions, not   ** including the temp database. (b) is important because if more than   ** one database file has an open write transaction, a master journal  ** file is required for an atomic commit.  */   for(i=0; i<db->nDb; i++){     Btree *pBt = db->aDb[i].pBt;    if( sqlite3BtreeIsInTrans(pBt) ){      needXcommit = 1;      if( i!=1 ) nTrans++;    }  }  /* If there are any write-transactions at all, invoke the commit hook */  if( needXcommit && db->xCommitCallback ){    (void)sqlite3SafetyOff(db);    rc = db->xCommitCallback(db->pCommitArg);    (void)sqlite3SafetyOn(db);    if( rc ){      return SQLITE_CONSTRAINT;    }  }  /* The simple case - no more than one database file (not counting the  ** TEMP database) has a transaction active.   There is no need for the  ** master-journal.  **  ** If the return value of sqlite3BtreeGetFilename() is a zero length  ** string, it means the main database is :memory: or a temp file.  In   ** that case we do not support atomic multi-file commits, so use the   ** simple case then too.  */  if( 0==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){       Btree *pBt = db->aDb[i].pBt;      if( pBt ){        rc = sqlite3BtreeCommitPhaseOne(pBt, 0);      }    }    /* Do the commit only if all databases successfully complete phase 1.     ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an    ** IO error while deleting or truncating a journal file. It is unlikely,    ** but could happen. In this case abandon processing and return the error.    */    for(i=0; rc==SQLITE_OK && i<db->nDb; i++){      Btree *pBt = db->aDb[i].pBt;      if( pBt ){        rc = sqlite3BtreeCommitPhaseTwo(pBt);      }    }    if( rc==SQLITE_OK ){      sqlite3VtabCommit(db);    }  }  /* The complex case - There is a multi-file write-transaction active.  ** This requires a master journal file to ensure the transaction is  ** committed atomicly.  */#ifndef SQLITE_OMIT_DISKIO  else{    sqlite3_vfs *pVfs = db->pVfs;    int needSync = 0;    char *zMaster = 0;   /* File-name for the master journal */    char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);    sqlite3_file *pMaster = 0;    i64 offset = 0;    int res;    /* Select a master journal file name */    do {      u32 random;      sqlite3DbFree(db, zMaster);      sqlite3_randomness(sizeof(random), &random);      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, random&0x7fffffff);      if( !zMaster ){        return SQLITE_NOMEM;      }      rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);    }while( rc==SQLITE_OK && res );    if( rc==SQLITE_OK ){      /* Open the master journal. */      rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster,           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|          SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0      );    }    if( rc!=SQLITE_OK ){      sqlite3DbFree(db, zMaster);      return rc;    }     /* Write the name of each database file in the transaction into the new    ** master journal file. If an error occurs at this point close    ** and delete the master journal file. All the individual journal files    ** still have 'null' as the master journal pointer, so they will roll    ** back independently if a failure occurs.    */    for(i=0; i<db->nDb; i++){      Btree *pBt = db->aDb[i].pBt;      if( i==1 ) continue;   /* Ignore the TEMP database */      if( sqlite3BtreeIsInTrans(pBt) ){        char const *zFile = sqlite3BtreeGetJournalname(pBt);        if( zFile[0]==0 ) continue;  /* Ignore :memory: databases */        if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){

⌨️ 快捷键说明

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