Exemple #1
0
/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
**     argv[0] = name of thing being created
**     argv[1] = root page number for table or index. 0 for trigger or view.
**     argv[2] = SQL text for the CREATE statement.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb = pData->iDb;

  assert( argc==3 );
  UNUSED_PARAMETER2(NotUsed, argc);
  assert( sqlite3_mutex_held(db->mutex) );
  DbClearProperty(db, iDb, DB_Empty);
  if( db->mallocFailed ){
    corruptSchema(pData, argv[0], 0);
    return 1;
  }

  assert( iDb>=0 && iDb<db->nDb );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 ){
    corruptSchema(pData, argv[0], 0);
  }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    int rc;
    u8 saved_iDb = db->init.iDb;
    sqlite3_stmt *pStmt;
    TESTONLY(int rcp);            /* Return code from sqlite3_prepare() */

    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = sqlite3Atoi(argv[1]);
    db->init.orphanTrigger = 0;
    TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
    rc = db->errCode;
    assert( (rc&0xFF)==(rcp&0xFF) );
    db->init.iDb = saved_iDb;
    assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          sqlite3OomFault(db);
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv[0], sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
Exemple #2
0
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed) {
    InitData *pData = (InitData*)pInit;
    sqlite3 *db = pData->db;
    int iDb = pData->iDb;

    assert( argc==3 );
    UNUSED_PARAMETER2(NotUsed, argc);
    assert( sqlite3_mutex_held(db->mutex) );
    DbClearProperty(db, iDb, DB_Empty);
    if( db->mallocFailed ) {
        corruptSchema(pData, argv[0], 0);
        return 1;
    }

    assert( iDb>=0 && iDb<db->nDb );
    if( argv==0 ) return 0;
    if( argv[1]==0 ) {
        corruptSchema(pData, argv[0], 0);
    } else if( argv[2] && argv[2][0] ) {
        int rc;
        sqlite3_stmt *pStmt;
        TESTONLY(int rcp);

        assert( db->init.busy );
        db->init.iDb = iDb;
        db->init.newTnum = sqlite3Atoi(argv[1]);
        db->init.orphanTrigger = 0;
        TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
        rc = db->errCode;
        assert( (rc&0xFF)==(rcp&0xFF) );
        db->init.iDb = 0;
        if( SQLITE_OK!=rc ) {
            if( db->init.orphanTrigger ) {
                assert( iDb==1 );
            } else {
                pData->rc = rc;
                if( rc==SQLITE_NOMEM ) {
                    db->mallocFailed = 1;
                } else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ) {
                    corruptSchema(pData, argv[0], sqlite3_errmsg(db));
                }
            }
        }
        sqlite3_finalize(pStmt);
    } else if( argv[0]==0 ) {
Exemple #3
0
/*
** This is the callback routine for the code that initializes the
** database.  See sqlite3Init() below for additional information.
** This routine is also called from the OP_ParseSchema opcode of the VDBE.
**
** Each callback contains the following information:
**
**     argv[0] = name of thing being created
**     argv[1] = root page number for table or index. 0 for trigger or view.
**     argv[2] = SQL text for the CREATE statement.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
  InitData *pData = (InitData*)pInit;
  sqlite3 *db = pData->db;
  int iDb = pData->iDb;

  pData->rc = SQLITE_OK;
  DbClearProperty(db, iDb, DB_Empty);
  if( sqlite3MallocFailed() ){
    corruptSchema(pData, 0);
    return SQLITE_NOMEM;
  }

  assert( argc==3 );
  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
  if( argv[1]==0 ){
    corruptSchema(pData, 0);
    return 1;
  }
  assert( iDb>=0 && iDb<db->nDb );
  if( argv[2] && argv[2][0] ){
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    char *zErr;
    int rc;
    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
    db->init.iDb = 0;
    assert( rc!=SQLITE_OK || zErr==0 );
    if( SQLITE_OK!=rc ){
      pData->rc = rc;
      if( rc==SQLITE_NOMEM ){
        sqlite3FailedMalloc();
      }else if( rc!=SQLITE_INTERRUPT ){
        corruptSchema(pData, zErr);
      }
      sqlite3_free(zErr);
      return 1;
    }
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
    ** been created when we processed the CREATE TABLE.  All we have
    ** to do here is record the root page number for that index.
    */
    Index *pIndex;
    pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName);
    if( pIndex==0 || pIndex->tnum!=0 ){
      /* This can occur if there exists an index on a TEMP table which
      ** has the same name as another index on a permanent index.  Since
      ** the permanent table is hidden by the TEMP table, we can also
      ** safely ignore the index on the permanent table.
      */
      /* Do Nothing */;
    }else{
      pIndex->tnum = atoi(argv[1]);
    }
  }
  return 0;
}
Exemple #4
0
/*
** This routine is called after the body of the procedure has been parsed
** in order to complete the process of building the procedure object.
*/
void sqliteFinishProc(
  Parse *pParse,          /* Parser context */
  Block *pBlock,		  /* The procedure body */
  Token *pAll             /* Token that describes the complete CREATE text */
){
  Object *no = 0;           /* The object whose construction is finishing up */
  sqlite *db = pParse->db;  /* The database */
  Vdbe *v = sqliteGetVdbe(pParse);

  if( pParse->nErr || pParse->pNewObject==0 ) goto objectfinish_cleanup;
  no = pParse->pNewObject;
  pParse->pNewObject = 0;

  sqliteCompileBlock(pParse, pBlock);
  sqliteVdbeAddOp(v, OP_Halt, 0, 0);

  /* save compiled body code, reset vdbe */
  if( !pParse->explain ){
    no->nOp = v->nOp;
    v->nOp = 0;
    no->aOp = v->aOp;
    v->aOp = 0;
    v->nOpAlloc = 0;
  }
  DbClearProperty(db, 0, DB_Locked);
  DbClearProperty(db, 1, DB_Locked);

  /* if we are not initializing build the sqlite_master entry */
  if( !db->init.busy ){
    static VdbeOpList insertObj[] = {
      { OP_NewRecno,   0, 0,  0           },
      { OP_String,     0, 0,  "procedure" },
      { OP_String,     0, 0,  0           },  /* 2: object name */
      { OP_String,     0, 0,  0           },  
      { OP_Integer,    0, 0,  0           },
      { OP_String,     0, 0,  0           },  /* 5: SQL */
      { OP_MakeRecord, 5, 0,  0           },
      { OP_PutIntKey,  0, 0,  0           },
    };
    int addr;

    /* Make an entry in the sqlite_master table */
    if( v==0 ) goto objectfinish_cleanup;
    sqliteBeginWriteOperation(pParse, 0, 0);
    sqliteOpenMasterTable(v, 0);
    addr = sqliteVdbeAddOpList(v, ArraySize(insertObj), insertObj);
    sqliteVdbeChangeP3(v, addr+2, no->name, 0); 
    sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
    if( no->iDb==0 ){
      sqliteChangeCookie(db, v);
    }
    sqliteVdbeAddOp(v, OP_Close, 0, 0);
    sqliteEndWriteOperation(pParse);
  }

  if( !pParse->explain ){
    sqliteHashInsert(&db->aDb[no->iDb].objectHash, 
                     no->name, strlen(no->name)+1, no);
    no = 0;
  }

objectfinish_cleanup:
  sqliteDeleteObject(no);
  sqliteDeleteObject(pParse->pNewObject);
  pParse->pNewObject = 0;
}