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

📄 prepare.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* Once all the other databases have been initialised, load the schema  ** for the TEMP database. This is loaded last, as the TEMP database  ** schema may contain references to objects in other databases.  */#ifndef SQLITE_OMIT_TEMPDB  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){    rc = sqlite3InitOne(db, 1, pzErrMsg);    if( rc ){      sqlite3ResetInternalSchema(db, 1);    }  }#endif  db->init.busy = 0;  if( rc==SQLITE_OK && commit_internal ){    sqlite3CommitInternalChanges(db);  }  return rc; }/*** This routine is a no-op if the database schema is already initialised.** Otherwise, the schema is loaded. An error code is returned.*/int sqlite3ReadSchema(Parse *pParse){  int rc = SQLITE_OK;  sqlite3 *db = pParse->db;  assert( sqlite3_mutex_held(db->mutex) );  if( !db->init.busy ){    rc = sqlite3Init(db, &pParse->zErrMsg);  }  if( rc!=SQLITE_OK ){    pParse->rc = rc;    pParse->nErr++;  }  return rc;}/*** Check schema cookies in all databases.  If any cookie is out** of date, return 0.  If all schema cookies are current, return 1.*/static int schemaIsValid(sqlite3 *db){  int iDb;  int rc;  BtCursor *curTemp;  int cookie;  int allOk = 1;  curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize());  if( curTemp ){    assert( sqlite3_mutex_held(db->mutex) );    for(iDb=0; allOk && iDb<db->nDb; iDb++){      Btree *pBt;      pBt = db->aDb[iDb].pBt;      if( pBt==0 ) continue;      memset(curTemp, 0, sqlite3BtreeCursorSize());      rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp);      if( rc==SQLITE_OK ){        rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);        if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){          allOk = 0;        }        sqlite3BtreeCloseCursor(curTemp);      }      if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){        db->mallocFailed = 1;      }    }    sqlite3_free(curTemp);  }else{    allOk = 0;    db->mallocFailed = 1;  }  return allOk;}/*** Convert a schema pointer into the iDb index that indicates** which database file in db->aDb[] the schema refers to.**** If the same database is attached more than once, the first** attached database is returned.*/int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){  int i = -1000000;  /* If pSchema is NULL, then return -1000000. This happens when code in   ** expr.c is trying to resolve a reference to a transient table (i.e. one  ** created by a sub-select). In this case the return value of this   ** function should never be used.  **  ** We return -1000000 instead of the more usual -1 simply because using  ** -1000000 as incorrectly using -1000000 index into db->aDb[] is much   ** more likely to cause a segfault than -1 (of course there are assert()  ** statements too, but it never hurts to play the odds).  */  assert( sqlite3_mutex_held(db->mutex) );  if( pSchema ){    for(i=0; i<db->nDb; i++){      if( db->aDb[i].pSchema==pSchema ){        break;      }    }    assert( i>=0 &&i>=0 &&  i<db->nDb );  }  return i;}/*** Compile the UTF-8 encoded SQL statement zSql into a statement handle.*/static int sqlite3Prepare(  sqlite3 *db,              /* Database handle. */  const char *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const char **pzTail       /* OUT: End of parsed string */){  Parse sParse;  char *zErrMsg = 0;  int rc = SQLITE_OK;  int i;  assert( ppStmt );  *ppStmt = 0;  if( sqlite3SafetyOn(db) ){    return SQLITE_MISUSE;  }  assert( !db->mallocFailed );  assert( sqlite3_mutex_held(db->mutex) );  /* If any attached database schemas are locked, do not proceed with  ** compilation. Instead return SQLITE_LOCKED immediately.  */  for(i=0; i<db->nDb; i++) {    Btree *pBt = db->aDb[i].pBt;    if( pBt ){      int rc;      rc = sqlite3BtreeSchemaLocked(pBt);      if( rc ){        const char *zDb = db->aDb[i].zName;        sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);        (void)sqlite3SafetyOff(db);        return sqlite3ApiExit(db, SQLITE_LOCKED);      }    }  }    memset(&sParse, 0, sizeof(sParse));  sParse.db = db;  if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){    char *zSqlCopy;    int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];    if( nBytes>mxLen ){      sqlite3Error(db, SQLITE_TOOBIG, "statement too long");      (void)sqlite3SafetyOff(db);      return sqlite3ApiExit(db, SQLITE_TOOBIG);    }    zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);    if( zSqlCopy ){      sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg);      sqlite3DbFree(db, zSqlCopy);      sParse.zTail = &zSql[sParse.zTail-zSqlCopy];    }else{      sParse.zTail = &zSql[nBytes];    }  }else{    sqlite3RunParser(&sParse, zSql, &zErrMsg);  }  if( db->mallocFailed ){    sParse.rc = SQLITE_NOMEM;  }  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;  if( sParse.checkSchema && !schemaIsValid(db) ){    sParse.rc = SQLITE_SCHEMA;  }  if( sParse.rc==SQLITE_SCHEMA ){    sqlite3ResetInternalSchema(db, 0);  }  if( db->mallocFailed ){    sParse.rc = SQLITE_NOMEM;  }  if( pzTail ){    *pzTail = sParse.zTail;  }  rc = sParse.rc;#ifndef SQLITE_OMIT_EXPLAIN  if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){    if( sParse.explain==2 ){      sqlite3VdbeSetNumCols(sParse.pVdbe, 3);      sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "order", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "from", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "detail", P4_STATIC);    }else{      sqlite3VdbeSetNumCols(sParse.pVdbe, 8);      sqlite3VdbeSetColName(sParse.pVdbe, 0, COLNAME_NAME, "addr", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 1, COLNAME_NAME, "opcode", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 2, COLNAME_NAME, "p1", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 5, COLNAME_NAME, "p4", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 6, COLNAME_NAME, "p5", P4_STATIC);      sqlite3VdbeSetColName(sParse.pVdbe, 7, COLNAME_NAME, "comment",P4_STATIC);    }  }#endif  if( sqlite3SafetyOff(db) ){    rc = SQLITE_MISUSE;  }  if( saveSqlFlag ){    sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql);  }  if( rc!=SQLITE_OK || db->mallocFailed ){    sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);    assert(!(*ppStmt));  }else{    *ppStmt = (sqlite3_stmt*)sParse.pVdbe;  }  if( zErrMsg ){    sqlite3Error(db, rc, "%s", zErrMsg);    sqlite3DbFree(db, zErrMsg);  }else{    sqlite3Error(db, rc, 0);  }  rc = sqlite3ApiExit(db, rc);  assert( (rc&db->errMask)==rc );  return rc;}static int sqlite3LockAndPrepare(  sqlite3 *db,              /* Database handle. */  const char *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  int saveSqlFlag,          /* True to copy SQL text into the sqlite3_stmt */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const char **pzTail       /* OUT: End of parsed string */){  int rc;  if( !sqlite3SafetyCheckOk(db) ){    return SQLITE_MISUSE;  }  sqlite3_mutex_enter(db->mutex);  sqlite3BtreeEnterAll(db);  rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail);  sqlite3BtreeLeaveAll(db);  sqlite3_mutex_leave(db->mutex);  return rc;}/*** Rerun the compilation of a statement after a schema change.** Return true if the statement was recompiled successfully.** Return false if there is an error of some kind.*/int sqlite3Reprepare(Vdbe *p){  int rc;  sqlite3_stmt *pNew;  const char *zSql;  sqlite3 *db;  assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) );  zSql = sqlite3_sql((sqlite3_stmt *)p);  assert( zSql!=0 );  /* Reprepare only called for prepare_v2() statements */  db = sqlite3VdbeDb(p);  assert( sqlite3_mutex_held(db->mutex) );  rc = sqlite3LockAndPrepare(db, zSql, -1, 0, &pNew, 0);  if( rc ){    if( rc==SQLITE_NOMEM ){      db->mallocFailed = 1;    }    assert( pNew==0 );    return 0;  }else{    assert( pNew!=0 );  }  sqlite3VdbeSwap((Vdbe*)pNew, p);  sqlite3_transfer_bindings(pNew, (sqlite3_stmt*)p);  sqlite3VdbeResetStepResult((Vdbe*)pNew);  sqlite3VdbeFinalize((Vdbe*)pNew);  return 1;}/*** Two versions of the official API.  Legacy and new use.  In the legacy** version, the original SQL text is not saved in the prepared statement** and so if a schema change occurs, SQLITE_SCHEMA is returned by** sqlite3_step().  In the new version, the original SQL text is retained** and the statement is automatically recompiled if an schema change** occurs.*/int sqlite3_prepare(  sqlite3 *db,              /* Database handle. */  const char *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const char **pzTail       /* OUT: End of parsed string */){  int rc;  rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,ppStmt,pzTail);  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */  return rc;}int sqlite3_prepare_v2(  sqlite3 *db,              /* Database handle. */  const char *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const char **pzTail       /* OUT: End of parsed string */){  int rc;  rc = sqlite3LockAndPrepare(db,zSql,nBytes,1,ppStmt,pzTail);  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */  return rc;}#ifndef SQLITE_OMIT_UTF16/*** Compile the UTF-16 encoded SQL statement zSql into a statement handle.*/static int sqlite3Prepare16(  sqlite3 *db,              /* Database handle. */   const void *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  int saveSqlFlag,          /* True to save SQL text into the sqlite3_stmt */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const void **pzTail       /* OUT: End of parsed string */){  /* This function currently works by first transforming the UTF-16  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The  ** tricky bit is figuring out the pointer to return in *pzTail.  */  char *zSql8;  const char *zTail8 = 0;  int rc = SQLITE_OK;  if( !sqlite3SafetyCheckOk(db) ){    return SQLITE_MISUSE;  }  sqlite3_mutex_enter(db->mutex);  zSql8 = sqlite3Utf16to8(db, zSql, nBytes);  if( zSql8 ){    rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);  }  if( zTail8 && pzTail ){    /* If sqlite3_prepare returns a tail pointer, we calculate the    ** equivalent pointer into the UTF-16 string by counting the unicode    ** characters between zSql8 and zTail8, and then returning a pointer    ** the same number of characters into the UTF-16 string.    */    int chars_parsed = sqlite3Utf8CharLen(zSql8, zTail8-zSql8);    *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed);  }  sqlite3DbFree(db, zSql8);   rc = sqlite3ApiExit(db, rc);  sqlite3_mutex_leave(db->mutex);  return rc;}/*** Two versions of the official API.  Legacy and new use.  In the legacy** version, the original SQL text is not saved in the prepared statement** and so if a schema change occurs, SQLITE_SCHEMA is returned by** sqlite3_step().  In the new version, the original SQL text is retained** and the statement is automatically recompiled if an schema change** occurs.*/int sqlite3_prepare16(  sqlite3 *db,              /* Database handle. */   const void *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const void **pzTail       /* OUT: End of parsed string */){  int rc;  rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */  return rc;}int sqlite3_prepare16_v2(  sqlite3 *db,              /* Database handle. */   const void *zSql,         /* UTF-8 encoded SQL statement. */  int nBytes,               /* Length of zSql in bytes. */  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */  const void **pzTail       /* OUT: End of parsed string */){  int rc;  rc = sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);  assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */  return rc;}#endif /* SQLITE_OMIT_UTF16 */

⌨️ 快捷键说明

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