/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
**
** There are up to 5 names for each column.  useType determines which
** name is returned.  Here are the names:
**
**    0      The column name as it should be displayed for output
**    1      The datatype name for the column
**    2      The name of the database that the column derives from
**    3      The name of the table that the column derives from
**    4      The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
    sqlite4_stmt *pStmt,
    int N,
    const void *(*xFunc)(Mem*, int *),
    int useType
) {
    const void *ret = 0;
    Vdbe *p = (Vdbe *)pStmt;
    int n;
    sqlite4 *db = p->db;

    assert( db!=0 );
    n = sqlite4_column_count(pStmt);
    if( N<n && N>=0 ) {
        N += useType*n;
        sqlite4_mutex_enter(db->mutex);
        assert( db->mallocFailed==0 );
        ret = xFunc(&p->aColName[N], 0);
        /* A malloc may have failed inside of the xFunc() call. If this
        ** is the case, clear the mallocFailed flag and return NULL.
        */
        if( db->mallocFailed ) {
            db->mallocFailed = 0;
            ret = 0;
        }
        sqlite4_mutex_leave(db->mutex);
    }
    return ret;
}
Пример #2
0
/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
**
** There are up to 5 names for each column.  useType determines which
** name is returned.  Here are the names:
**
**    0      The column name as it should be displayed for output
**    1      The datatype name for the column
**    2      The name of the database that the column derives from
**    3      The name of the table that the column derives from
**    4      The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  Vdbe *p = (Vdbe *)pStmt;
  int n = sqlite3_column_count(pStmt);

  if( p==0 || N>=n || N<0 ){
    return 0;
  }
  N += useType*n;
  return xFunc(&p->aColName[N]);
}
Пример #3
0
/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
**
** There are up to 5 names for each column.  useType determines which
** name is returned.  Here are the names:
**
**    0      The column name as it should be displayed for output
**    1      The datatype name for the column
**    2      The name of the database that the column derives from
**    3      The name of the table that the column derives from
**    4      The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  const void *ret;
  Vdbe *p = (Vdbe *)pStmt;
  int n = sqlite3_column_count(pStmt);

  if( p==0 || N>=n || N<0 ){
    return 0;
  }
  N += useType*n;
  ret = xFunc(&p->aColName[N]);

  /* A malloc may have failed inside of the xFunc() call. If this is the case,
  ** clear the mallocFailed flag and return NULL.
  */
  sqlite3ApiExit(0, 0);
  return ret;
}
Пример #4
0
/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
**
** There are up to 5 names for each column.  useType determines which
** name is returned.  Here are the names:
**
**    0      The column name as it should be displayed for output
**    1      The datatype name for the column
**    2      The name of the database that the column derives from
**    3      The name of the table that the column derives from
**    4      The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
  sqlite3_stmt *pStmt,
  int N,
  const void *(*xFunc)(Mem*),
  int useType
){
  const void *ret;
  Vdbe *p;
  int n;
  sqlite3 *db;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pStmt==0 ){
    (void)SQLITE_MISUSE_BKPT;
    return 0;
  }
#endif
  ret = 0;
  p = (Vdbe *)pStmt;
  db = p->db;
  assert( db!=0 );
  n = sqlite3_column_count(pStmt);
  if( N<n && N>=0 ){
    N += useType*n;
    sqlite3_mutex_enter(db->mutex);
    assert( db->mallocFailed==0 );
    ret = xFunc(&p->aColName[N]);
     /* A malloc may have failed inside of the xFunc() call. If this
    ** is the case, clear the mallocFailed flag and return NULL.
    */
    if( db->mallocFailed ){
      db->mallocFailed = 0;
      ret = 0;
    }
    sqlite3_mutex_leave(db->mutex);
  }
  return ret;
}
Пример #5
0
/*
** This routine is called the when a VDBE tries to halt.  If the VDBE
** has made changes and is in autocommit mode, then commit those
** changes.  If a rollback is needed, then do the rollback.
**
** This routine is the only way to move the state of a VM from
** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.
**
** Return an error code.  If the commit could not complete because of
** lock contention, return SQLITE_BUSY.  If SQLITE_BUSY is returned, it
** means the close did not happen and needs to be repeated.
*/
int sqlite3VdbeHalt(Vdbe *p){
  sqlite3 *db = p->db;
  int i;
  int (*xFunc)(Btree *pBt) = 0;  /* Function to call on each btree backend */

  if( p->magic!=VDBE_MAGIC_RUN ){
    /* Already halted.  Nothing to do. */
    assert( p->magic==VDBE_MAGIC_HALT );
    return SQLITE_OK;
  }
  closeAllCursors(p);
  checkActiveVdbeCnt(db);
  if( db->autoCommit && db->activeVdbeCnt==1 ){
    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      /* The auto-commit flag is true, there are no other active queries
      ** using this handle and the vdbe program was successful or hit an
      ** 'OR FAIL' constraint. This means a commit is required.
      */
      int rc = vdbeCommit(db);
      if( rc==SQLITE_BUSY ){
        return SQLITE_BUSY;
      }else if( rc!=SQLITE_OK ){
        p->rc = rc;
        xFunc = sqlite3BtreeRollback;
      }
    }else{
      xFunc = sqlite3BtreeRollback;
    }
  }else{
    if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
      xFunc = sqlite3BtreeCommitStmt;
    }else if( p->errorAction==OE_Abort ){
      xFunc = sqlite3BtreeRollbackStmt;
    }else{
      xFunc = sqlite3BtreeRollback;
      db->autoCommit = 1;
      abortOtherActiveVdbes(p);
    }
  }

  /* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
  ** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
  ** each backend. If an error occurs and the return code is still
  ** SQLITE_OK, set the return code to the new error value.
  */
  for(i=0; xFunc && i<db->nDb; i++){ 
    int rc;
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ){
      rc = xFunc(pBt);
      if( p->rc==SQLITE_OK ) p->rc = rc;
    }
  }

  /* If this was an INSERT, UPDATE or DELETE, set the change counter. */
  if( p->changeCntOn ){
    if( !xFunc || xFunc==sqlite3BtreeCommitStmt ){
      sqlite3VdbeSetChanges(db, p->nChange);
    }else{
      sqlite3VdbeSetChanges(db, 0);
    }
    p->nChange = 0;
  }

  /* Rollback or commit any schema changes that occurred. */
  if( p->rc!=SQLITE_OK ){
    sqlite3RollbackInternalChanges(db);
  }else if( db->flags & SQLITE_InternChanges ){
    sqlite3CommitInternalChanges(db);
  }

  /* We have successfully halted and closed the VM.  Record this fact. */
  if( p->pc>=0 ){
    db->activeVdbeCnt--;
  }
  p->magic = VDBE_MAGIC_HALT;
  checkActiveVdbeCnt(db);

  return SQLITE_OK;
}