17c478bdstevel@tonic-gate
27c478bdstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
37c478bdstevel@tonic-gate
47c478bdstevel@tonic-gate/*
57c478bdstevel@tonic-gate** 2001 September 15
67c478bdstevel@tonic-gate**
77c478bdstevel@tonic-gate** The author disclaims copyright to this source code.  In place of
87c478bdstevel@tonic-gate** a legal notice, here is a blessing:
97c478bdstevel@tonic-gate**
107c478bdstevel@tonic-gate**    May you do good and not evil.
117c478bdstevel@tonic-gate**    May you find forgiveness for yourself and forgive others.
127c478bdstevel@tonic-gate**    May you share freely, never taking more than you give.
137c478bdstevel@tonic-gate**
147c478bdstevel@tonic-gate*************************************************************************
157c478bdstevel@tonic-gate** Main file for the SQLite library.  The routines in this file
167c478bdstevel@tonic-gate** implement the programmer interface to the library.  Routines in
177c478bdstevel@tonic-gate** other files are for internal use by SQLite and should not be
187c478bdstevel@tonic-gate** accessed by users of the library.
197c478bdstevel@tonic-gate**
207c478bdstevel@tonic-gate** $Id: main.c,v 1.164.2.2 2004/06/26 14:40:05 drh Exp $
217c478bdstevel@tonic-gate*/
227c478bdstevel@tonic-gate#include "sqliteInt.h"
237c478bdstevel@tonic-gate#include "os.h"
247c478bdstevel@tonic-gate#include <ctype.h>
257c478bdstevel@tonic-gate
267c478bdstevel@tonic-gate/*
277c478bdstevel@tonic-gate** A pointer to this structure is used to communicate information
287c478bdstevel@tonic-gate** from sqliteInit into the sqliteInitCallback.
297c478bdstevel@tonic-gate*/
307c478bdstevel@tonic-gatetypedef struct {
317c478bdstevel@tonic-gate  sqlite *db;         /* The database being initialized */
327c478bdstevel@tonic-gate  char **pzErrMsg;    /* Error message stored here */
337c478bdstevel@tonic-gate} InitData;
347c478bdstevel@tonic-gate
357c478bdstevel@tonic-gate/*
367c478bdstevel@tonic-gate** Fill the InitData structure with an error message that indicates
377c478bdstevel@tonic-gate** that the database is corrupt.
387c478bdstevel@tonic-gate*/
397c478bdstevel@tonic-gatestatic void corruptSchema(InitData *pData, const char *zExtra){
407c478bdstevel@tonic-gate  sqliteSetString(pData->pzErrMsg, "malformed database schema",
417c478bdstevel@tonic-gate     zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
427c478bdstevel@tonic-gate}
437c478bdstevel@tonic-gate
447c478bdstevel@tonic-gate/*
457c478bdstevel@tonic-gate** This is the callback routine for the code that initializes the
467c478bdstevel@tonic-gate** database.  See sqliteInit() below for additional information.
477c478bdstevel@tonic-gate**
487c478bdstevel@tonic-gate** Each callback contains the following information:
497c478bdstevel@tonic-gate**
507c478bdstevel@tonic-gate**     argv[0] = "file-format" or "schema-cookie" or "table" or "index"
517c478bdstevel@tonic-gate**     argv[1] = table or index name or meta statement type.
527c478bdstevel@tonic-gate**     argv[2] = root page number for table or index.  NULL for meta.
537c478bdstevel@tonic-gate**     argv[3] = SQL text for a CREATE TABLE or CREATE INDEX statement.
547c478bdstevel@tonic-gate**     argv[4] = "1" for temporary files, "0" for main database, "2" or more
557c478bdstevel@tonic-gate**               for auxiliary database files.
567c478bdstevel@tonic-gate**
577c478bdstevel@tonic-gate*/
587c478bdstevel@tonic-gatestatic
597c478bdstevel@tonic-gateint sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){
607c478bdstevel@tonic-gate  InitData *pData = (InitData*)pInit;
617c478bdstevel@tonic-gate  int nErr = 0;
627c478bdstevel@tonic-gate
637c478bdstevel@tonic-gate  assert( argc==5 );
647c478bdstevel@tonic-gate  if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
657c478bdstevel@tonic-gate  if( argv[0]==0 ){
667c478bdstevel@tonic-gate    corruptSchema(pData, 0);
677c478bdstevel@tonic-gate    return 1;
687c478bdstevel@tonic-gate  }
697c478bdstevel@tonic-gate  switch( argv[0][0] ){
707c478bdstevel@tonic-gate    case 'v':
717c478bdstevel@tonic-gate    case 'i':
727c478bdstevel@tonic-gate    case 't': {  /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */
737c478bdstevel@tonic-gate      sqlite *db = pData->db;
747c478bdstevel@tonic-gate      if( argv[2]==0 || argv[4]==0 ){
757c478bdstevel@tonic-gate        corruptSchema(pData, 0);
767c478bdstevel@tonic-gate        return 1;
777c478bdstevel@tonic-gate      }
787c478bdstevel@tonic-gate      if( argv[3] && argv[3][0] ){
797c478bdstevel@tonic-gate        /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
807c478bdstevel@tonic-gate        ** But because db->init.busy is set to 1, no VDBE code is generated
817c478bdstevel@tonic-gate        ** or executed.  All the parser does is build the internal data
827c478bdstevel@tonic-gate        ** structures that describe the table, index, or view.
837c478bdstevel@tonic-gate        */
847c478bdstevel@tonic-gate        char *zErr;
857c478bdstevel@tonic-gate        assert( db->init.busy );
867c478bdstevel@tonic-gate        db->init.iDb = atoi(argv[4]);
877c478bdstevel@tonic-gate        assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
887c478bdstevel@tonic-gate        db->init.newTnum = atoi(argv[2]);
897c478bdstevel@tonic-gate        if( sqlite_exec(db, argv[3], 0, 0, &zErr) ){
907c478bdstevel@tonic-gate          corruptSchema(pData, zErr);
917c478bdstevel@tonic-gate          sqlite_freemem(zErr);
927c478bdstevel@tonic-gate        }
937c478bdstevel@tonic-gate        db->init.iDb = 0;
947c478bdstevel@tonic-gate      }else{
957c478bdstevel@tonic-gate        /* If the SQL column is blank it means this is an index that
967c478bdstevel@tonic-gate        ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
977c478bdstevel@tonic-gate        ** constraint for a CREATE TABLE.  The index should have already
987c478bdstevel@tonic-gate        ** been created when we processed the CREATE TABLE.  All we have
997c478bdstevel@tonic-gate        ** to do here is record the root page number for that index.
1007c478bdstevel@tonic-gate        */
1017c478bdstevel@tonic-gate        int iDb;
1027c478bdstevel@tonic-gate        Index *pIndex;
1037c478bdstevel@tonic-gate
1047c478bdstevel@tonic-gate        iDb = atoi(argv[4]);
1057c478bdstevel@tonic-gate        assert( iDb>=0 && iDb<db->nDb );
1067c478bdstevel@tonic-gate        pIndex = sqliteFindIndex(db, argv[1], db->aDb[iDb].zName);
1077c478bdstevel@tonic-gate        if( pIndex==0 || pIndex->tnum!=0 ){
1087c478bdstevel@tonic-gate          /* This can occur if there exists an index on a TEMP table which
1097c478bdstevel@tonic-gate          ** has the same name as another index on a permanent index.  Since
1107c478bdstevel@tonic-gate          ** the permanent table is hidden by the TEMP table, we can also
1117c478bdstevel@tonic-gate          ** safely ignore the index on the permanent table.
1127c478bdstevel@tonic-gate          */
1137c478bdstevel@tonic-gate          /* Do Nothing */;
1147c478bdstevel@tonic-gate        }else{
1157c478bdstevel@tonic-gate          pIndex->tnum = atoi(argv[2]);
1167c478bdstevel@tonic-gate        }
1177c478bdstevel@tonic-gate      }
1187c478bdstevel@tonic-gate      break;
1197c478bdstevel@tonic-gate    }
1207c478bdstevel@tonic-gate    default: {
1217c478bdstevel@tonic-gate      /* This can not happen! */
1227c478bdstevel@tonic-gate      nErr = 1;
1237c478bdstevel@tonic-gate      assert( nErr==0 );
1247c478bdstevel@tonic-gate    }
1257c478bdstevel@tonic-gate  }
1267c478bdstevel@tonic-gate  return nErr;
1277c478bdstevel@tonic-gate}
1287c478bdstevel@tonic-gate
1297c478bdstevel@tonic-gate/*
1307c478bdstevel@tonic-gate** This is a callback procedure used to reconstruct a table.  The
1317c478bdstevel@tonic-gate** name of the table to be reconstructed is passed in as argv[0].
1327c478bdstevel@tonic-gate**
1337c478bdstevel@tonic-gate** This routine is used to automatically upgrade a database from
1347c478bdstevel@tonic-gate** format version 1 or 2 to version 3.  The correct operation of
1357c478bdstevel@tonic-gate** this routine relys on the fact that no indices are used when
1367c478bdstevel@tonic-gate** copying a table out to a temporary file.
1377c478bdstevel@tonic-gate**
1387c478bdstevel@tonic-gate** The change from version 2 to version 3 occurred between SQLite
1397c478bdstevel@tonic-gate** version 2.5.6 and 2.6.0 on 2002-July-18.
1407c478bdstevel@tonic-gate*/
1417c478bdstevel@tonic-gatestatic
1427c478bdstevel@tonic-gateint upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){
1437c478bdstevel@tonic-gate  InitData *pData = (InitData*)pInit;
1447c478bdstevel@tonic-gate  int rc;
1457c478bdstevel@tonic-gate  Table *pTab;
1467c478bdstevel@tonic-gate  Trigger *pTrig;
1477c478bdstevel@tonic-gate  char *zErr = 0;
1487c478bdstevel@tonic-gate
1497c478bdstevel@tonic-gate  pTab = sqliteFindTable(pData->db, argv[0], 0);
1507c478bdstevel@tonic-gate  assert( pTab!=0 );
1517c478bdstevel@tonic-gate  assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
1527c478bdstevel@tonic-gate  if( pTab ){
1537c478bdstevel@tonic-gate    pTrig = pTab->pTrigger;
1547c478bdstevel@tonic-gate    pTab->pTrigger = 0;  /* Disable all triggers before rebuilding the table */
1557c478bdstevel@tonic-gate  }
1567c478bdstevel@tonic-gate  rc = sqlite_exec_printf(pData->db,
1577c478bdstevel@tonic-gate    "CREATE TEMP TABLE sqlite_x AS SELECT * FROM '%q'; "
1587c478bdstevel@tonic-gate    "DELETE FROM '%q'; "
1597c478bdstevel@tonic-gate    "INSERT INTO '%q' SELECT * FROM sqlite_x; "
1607c478bdstevel@tonic-gate    "DROP TABLE sqlite_x;",
1617c478bdstevel@tonic-gate    0, 0, &zErr, argv[0], argv[0], argv[0]);
1627c478bdstevel@tonic-gate  if( zErr ){
1637c478bdstevel@tonic-gate    if( *pData->pzErrMsg ) sqlite_freemem(*pData->pzErrMsg);
1647c478bdstevel@tonic-gate    *pData->pzErrMsg = zErr;
1657c478bdstevel@tonic-gate  }
1667c478bdstevel@tonic-gate
1677c478bdstevel@tonic-gate  /* If an error occurred in the SQL above, then the transaction will
1687c478bdstevel@tonic-gate  ** rollback which will delete the internal symbol tables.  This will
1697c478bdstevel@tonic-gate  ** cause the structure that pTab points to be deleted.  In case that
1707c478bdstevel@tonic-gate  ** happened, we need to refetch pTab.
1717c478bdstevel@tonic-gate  */
1727c478bdstevel@tonic-gate  pTab = sqliteFindTable(pData->db, argv[0], 0);
1737c478bdstevel@tonic-gate  if( pTab ){
1747c478bdstevel@tonic-gate    assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
1757c478bdstevel@tonic-gate    pTab->pTrigger = pTrig;  /* Re-enable triggers */
1767c478bdstevel@tonic-gate  }
1777c478bdstevel@tonic-gate  return rc!=SQLITE_OK;
1787c478bdstevel@tonic-gate}
1797c478bdstevel@tonic-gate
1807c478bdstevel@tonic-gate
1817c478bdstevel@tonic-gate
1827c478bdstevel@tonic-gate/*
1837c478bdstevel@tonic-gate** Attempt to read the database schema and initialize internal
1847c478bdstevel@tonic-gate** data structures for a single database file.  The index of the
1857c478bdstevel@tonic-gate** database file is given by iDb.  iDb==0 is used for the main
1867c478bdstevel@tonic-gate** database.  iDb==1 should never be used.  iDb>=2 is used for
1877c478bdstevel@tonic-gate** auxiliary databases.  Return one of the SQLITE_ error codes to
1887c478bdstevel@tonic-gate** indicate success or failure.
1897c478bdstevel@tonic-gate*/
1907c478bdstevel@tonic-gatestatic int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
1917c478bdstevel@tonic-gate  int rc;
1927c478bdstevel@tonic-gate  BtCursor *curMain;
1937c478bdstevel@tonic-gate  int size;
1947c478bdstevel@tonic-gate  Table *pTab;
1957c478bdstevel@tonic-gate  char const *azArg[6];
1967c478bdstevel@tonic-gate  char zDbNum[30];
1977c478bdstevel@tonic-gate  int meta[SQLITE_N_BTREE_META];
1987c478bdstevel@tonic-gate  InitData initData;
1997c478bdstevel@tonic-gate  char const *zMasterSchema;
2007c478bdstevel@tonic-gate  char const *zMasterName;
2017c478bdstevel@tonic-gate  char *zSql = 0;
2027c478bdstevel@tonic-gate
2037c478bdstevel@tonic-gate  /*
2047c478bdstevel@tonic-gate  ** The master database table has a structure like this
2057c478bdstevel@tonic-gate  */
2067c478bdstevel@tonic-gate  static char master_schema[] =
2077c478bdstevel@tonic-gate     "CREATE TABLE sqlite_master(\n"
2087c478bdstevel@tonic-gate     "  type text,\n"
2097c478bdstevel@tonic-gate     "  name text,\n"
2107c478bdstevel@tonic-gate     "  tbl_name text,\n"
2117c478bdstevel@tonic-gate     "  rootpage integer,\n"
2127c478bdstevel@tonic-gate     "  sql text\n"
2137c478bdstevel@tonic-gate     ")"
2147c478bdstevel@tonic-gate  ;
2157c478bdstevel@tonic-gate  static char temp_master_schema[] =
2167c478bdstevel@tonic-gate     "CREATE TEMP TABLE sqlite_temp_master(\n"
2177c478bdstevel@tonic-gate     "  type text,\n"
2187c478bdstevel@tonic-gate     "  name text,\n"
2197c478bdstevel@tonic-gate     "  tbl_name text,\n"
2207c478bdstevel@tonic-gate     "  rootpage integer,\n"
2217c478bdstevel@tonic-gate     "  sql text\n"
2227c478bdstevel@tonic-gate     ")"
2237c478bdstevel@tonic-gate  ;
2247c478bdstevel@tonic-gate
2257c478bdstevel@tonic-gate  assert( iDb>=0 && iDb<db->nDb );
2267c478bdstevel@tonic-gate
2277c478bdstevel@tonic-gate  /* zMasterSchema and zInitScript are set to point at the master schema
2287c478bdstevel@tonic-gate  ** and initialisation script appropriate for the database being
2297c478bdstevel@tonic-gate  ** initialised. zMasterName is the name of the master table.
2307c478bdstevel@tonic-gate  */
2317c478bdstevel@tonic-gate  if( iDb==1 ){
2327c478bdstevel@tonic-gate    zMasterSchema = temp_master_schema;
2337c478bdstevel@tonic-gate    zMasterName = TEMP_MASTER_NAME;
2347c478bdstevel@tonic-gate  }else{
2357c478bdstevel@tonic-gate    zMasterSchema = master_schema;
2367c478bdstevel@tonic-gate    zMasterName = MASTER_NAME;
2377c478bdstevel@tonic-gate  }
2387c478bdstevel@tonic-gate
2397c478bdstevel@tonic-gate  /* Construct the schema table.
2407c478bdstevel@tonic-gate  */
2417c478bdstevel@tonic-gate  sqliteSafetyOff(db);
2427c478bdstevel@tonic-gate  azArg[0] = "table";
2437c478bdstevel@tonic-gate  azArg[1] = zMasterName;
2447c478bdstevel@tonic-gate  azArg[2] = "2";
2457c478bdstevel@tonic-gate  azArg[3] = zMasterSchema;
2467c478bdstevel@tonic-gate  sprintf(zDbNum, "%d", iDb);
2477c478bdstevel@tonic-gate  azArg[4] = zDbNum;
2487c478bdstevel@tonic-gate  azArg[5] = 0;
2497c478bdstevel@tonic-gate  initData.db = db;
2507c478bdstevel@tonic-gate  initData.pzErrMsg = pzErrMsg;
2517c478bdstevel@tonic-gate  sqliteInitCallback(&initData, 5, (char **)azArg, 0);
2527c478bdstevel@tonic-gate  pTab = sqliteFindTable(db, zMasterName, db->aDb[iDb].zName);
2537c478bdstevel@tonic-gate  if( pTab ){
2547c478bdstevel@tonic-gate    pTab->readOnly = 1;
2557c478bdstevel@tonic-gate  }else{
2567c478bdstevel@tonic-gate    return SQLITE_NOMEM;
2577c478bdstevel@tonic-gate  }
2587c478bdstevel@tonic-gate  sqliteSafetyOn(db);
2597c478bdstevel@tonic-gate
2607c478bdstevel@tonic-gate  /* Create a cursor to hold the database open
2617c478bdstevel@tonic-gate  */
2627c478bdstevel@tonic-gate  if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
2637c478bdstevel@tonic-gate  rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);
2647c478bdstevel@tonic-gate  if( rc ){
2657c478bdstevel@tonic-gate    sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
2667c478bdstevel@tonic-gate    return rc;
2677c478bdstevel@tonic-gate  }
2687c478bdstevel@tonic-gate
2697c478bdstevel@tonic-gate  /* Get the database meta information
2707c478bdstevel@tonic-gate  */
2717c478bdstevel@tonic-gate  rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta);
2727c478bdstevel@tonic-gate  if( rc ){
2737c478bdstevel@tonic-gate    sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
2747c478bdstevel@tonic-gate    sqliteBtreeCloseCursor(curMain);
2757c478bdstevel@tonic-gate    return rc;
2767c478bdstevel@tonic-gate  }
2777c478bdstevel@tonic-gate  db->aDb[iDb].schema_cookie = meta[1];
2787c478bdstevel@tonic-gate  if( iDb==0 ){
2797c478bdstevel@tonic-gate    db->next_cookie = meta[1];
2807c478bdstevel@tonic-gate    db->file_format = meta[2];
2817c478bdstevel@tonic-gate    size = meta[3];
2827c478bdstevel@tonic-gate    if( size==0 ){ size = MAX_PAGES; }
2837c478bdstevel@tonic-gate    db->cache_size = size;
2847c478bdstevel@tonic-gate    db->safety_level = meta[4];
2857c478bdstevel@tonic-gate    if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){
2867c478bdstevel@tonic-gate      db->temp_store = meta[6];
2877c478bdstevel@tonic-gate    }
2887c478bdstevel@tonic-gate    if( db->safety_level==0 ) db->safety_level = 2;
2897c478bdstevel@tonic-gate
2907c478bdstevel@tonic-gate    /*
2917c478bdstevel@tonic-gate    **  file_format==1    Version 2.1.0.
2927c478bdstevel@tonic-gate    **  file_format==2    Version 2.2.0. Add support for INTEGER PRIMARY KEY.
2937c478bdstevel@tonic-gate    **  file_format==3    Version 2.6.0. Fix empty-string index bug.
2947c478bdstevel@tonic-gate    **  file_format==4    Version 2.7.0. Add support for separate numeric and
2957c478bdstevel@tonic-gate    **                    text datatypes.
2967c478bdstevel@tonic-gate    */
2977c478bdstevel@tonic-gate    if( db->file_format==0 ){
2987c478bdstevel@tonic-gate      /* This happens if the database was initially empty */
2997c478bdstevel@tonic-gate      db->file_format = 4;
3007c478bdstevel@tonic-gate    }else if( db->file_format>4 ){
3017c478bdstevel@tonic-gate      sqliteBtreeCloseCursor(curMain);
3027c478bdstevel@tonic-gate      sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
3037c478bdstevel@tonic-gate      return SQLITE_ERROR;
3047c478bdstevel@tonic-gate    }
3057c478bdstevel@tonic-gate  }else if( iDb!=1 && (db->file_format!=meta[2] || db->file_format<4) ){
3067c478bdstevel@tonic-gate    assert( db->file_format>=4 );
3077c478bdstevel@tonic-gate    if( meta[2]==0 ){
3087c478bdstevel@tonic-gate      sqliteSetString(pzErrMsg, "cannot attach empty database: ",
3097c478bdstevel@tonic-gate         db->aDb[iDb].zName, (char*)0);
3107c478bdstevel@tonic-gate    }else{
3117c478bdstevel@tonic-gate      sqliteSetString(pzErrMsg, "incompatible file format in auxiliary "
3127c478bdstevel@tonic-gate         "database: ", db->aDb[iDb].zName, (char*)0);
3137c478bdstevel@tonic-gate    }
3147c478bdstevel@tonic-gate    sqliteBtreeClose(db->aDb[iDb].pBt);
3157c478bdstevel@tonic-gate    db->aDb[iDb].pBt = 0;
3167c478bdstevel@tonic-gate    return SQLITE_FORMAT;
3177c478bdstevel@tonic-gate  }
3187c478bdstevel@tonic-gate  sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
3197c478bdstevel@tonic-gate  sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
3207c478bdstevel@tonic-gate
3217c478bdstevel@tonic-gate  /* Read the schema information out of the schema tables
3227c478bdstevel@tonic-gate  */
3237c478bdstevel@tonic-gate  assert( db->init.busy );
3247c478bdstevel@tonic-gate  sqliteSafetyOff(db);
3257c478bdstevel@tonic-gate
3267c478bdstevel@tonic-gate  /* The following SQL will read the schema from the master tables.
3277c478bdstevel@tonic-gate  ** The first version works with SQLite file formats 2 or greater.
3287c478bdstevel@tonic-gate  ** The second version is for format 1 files.
3297c478bdstevel@tonic-gate  **
3307c478bdstevel@tonic-gate  ** Beginning with file format 2, the rowid for new table entries
3317c478bdstevel@tonic-gate  ** (including entries in sqlite_master) is an increasing integer.
3327c478bdstevel@tonic-gate  ** So for file format 2 and later, we can play back sqlite_master
3337c478bdstevel@tonic-gate  ** and all the CREATE statements will appear in the right order.
3347c478bdstevel@tonic-gate  ** But with file format 1, table entries were random and so we
3357c478bdstevel@tonic-gate  ** have to make sure the CREATE TABLEs occur before their corresponding
3367c478bdstevel@tonic-gate  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
3377c478bdstevel@tonic-gate  ** CREATE TRIGGER in file format 1 because those constructs did
3387c478bdstevel@tonic-gate  ** not exist then.)
3397c478bdstevel@tonic-gate  */
3407c478bdstevel@tonic-gate  if( db->file_format>=2 ){
3417c478bdstevel@tonic-gate    sqliteSetString(&zSql,
3427c478bdstevel@tonic-gate        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
3437c478bdstevel@tonic-gate       db->aDb[iDb].zName, "\".", zMasterName, (char*)0);
3447c478bdstevel@tonic-gate  }else{
3457c478bdstevel@tonic-gate    sqliteSetString(&zSql,
3467c478bdstevel@tonic-gate        "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
3477c478bdstevel@tonic-gate       db->aDb[iDb].zName, "\".", zMasterName,
3487c478bdstevel@tonic-gate       " WHERE type IN ('table', 'index')"
3497c478bdstevel@tonic-gate       " ORDER BY CASE type WHEN 'table' THEN 0 ELSE 1 END", (char*)0);
3507c478bdstevel@tonic-gate  }
3517c478bdstevel@tonic-gate  rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
3527c478bdstevel@tonic-gate
3537c478bdstevel@tonic-gate  sqliteFree(zSql);
3547c478bdstevel@tonic-gate  sqliteSafetyOn(db);
3557c478bdstevel@tonic-gate  sqliteBtreeCloseCursor(curMain);
3567c478bdstevel@tonic-gate  if( sqlite_malloc_failed ){
3577c478bdstevel@tonic-gate    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
3587c478bdstevel@tonic-gate    rc = SQLITE_NOMEM;
3597c478bdstevel@tonic-gate    sqliteResetInternalSchema(db, 0);
3607c478bdstevel@tonic-gate  }
3617c478bdstevel@tonic-gate  if( rc==SQLITE_OK ){
3627c478bdstevel@tonic-gate    DbSetProperty(db, iDb, DB_SchemaLoaded);
3637c478bdstevel@tonic-gate  }else{
3647c478bdstevel@tonic-gate    sqliteResetInternalSchema(db, iDb);
3657c478bdstevel@tonic-gate  }
3667c478bdstevel@tonic-gate  return rc;
3677c478bdstevel@tonic-gate}
3687c478bdstevel@tonic-gate
3697c478bdstevel@tonic-gate/*
3707c478bdstevel@tonic-gate** Initialize all database files - the main database file, the file
3717c478bdstevel@tonic-gate** used to store temporary tables, and any additional database files
3727c478bdstevel@tonic-gate** created using ATTACH statements.  Return a success code.  If an
3737c478bdstevel@tonic-gate** error occurs, write an error message into *pzErrMsg.
3747c478bdstevel@tonic-gate**
3757c478bdstevel@tonic-gate** After the database is initialized, the SQLITE_Initialized
3767c478bdstevel@tonic-gate** bit is set in the flags field of the sqlite structure.  An
3777c478bdstevel@tonic-gate** attempt is made to initialize the database as soon as it
3787c478bdstevel@tonic-gate** is opened.  If that fails (perhaps because another process
3797c478bdstevel@tonic-gate** has the sqlite_master table locked) than another attempt
3807c478bdstevel@tonic-gate** is made the first time the database is accessed.
3817c478bdstevel@tonic-gate*/
3827c478bdstevel@tonic-gateint sqliteInit(sqlite *db, char **pzErrMsg){
3837c478bdstevel@tonic-gate  int i, rc;
3847c478bdstevel@tonic-gate
3857c478bdstevel@tonic-gate  if( db->init.busy ) return SQLITE_OK;
3867c478bdstevel@tonic-gate  assert( (db->flags & SQLITE_Initialized)==0 );
3877c478bdstevel@tonic-gate  rc = SQLITE_OK;
3887c478bdstevel@tonic-gate  db->init.busy = 1;
3897c478bdstevel@tonic-gate  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
3907c478bdstevel@tonic-gate    if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
3917c478bdstevel@tonic-gate    rc = sqliteInitOne(db, i, pzErrMsg);
3927c478bdstevel@tonic-gate    if( rc ){
3937c478bdstevel@tonic-gate      sqliteResetInternalSchema(db, i);
3947c478bdstevel@tonic-gate    }
3957c478bdstevel@tonic-gate  }
3967c478bdstevel@tonic-gate
3977c478bdstevel@tonic-gate  /* Once all the other databases have been initialised, load the schema
3987c478bdstevel@tonic-gate  ** for the TEMP database. This is loaded last, as the TEMP database
3997c478bdstevel@tonic-gate  ** schema may contain references to objects in other databases.
4007c478bdstevel@tonic-gate  */
4017c478bdstevel@tonic-gate  if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
4027c478bdstevel@tonic-gate    rc = sqliteInitOne(db, 1, pzErrMsg);
4037c478bdstevel@tonic-gate    if( rc ){
4047c478bdstevel@tonic-gate      sqliteResetInternalSchema(db, 1);
4057c478bdstevel@tonic-gate    }
4067c478bdstevel@tonic-gate  }
4077c478bdstevel@tonic-gate
4087c478bdstevel@tonic-gate  db->init.busy = 0;
4097c478bdstevel@tonic-gate  if( rc==SQLITE_OK ){
4107c478bdstevel@tonic-gate    db->flags |= SQLITE_Initialized;
4117c478bdstevel@tonic-gate    sqliteCommitInternalChanges(db);
4127c478bdstevel@tonic-gate  }
4137c478bdstevel@tonic-gate
4147c478bdstevel@tonic-gate  /* If the database is in formats 1 or 2, then upgrade it to
4157c478bdstevel@tonic-gate  ** version 3.  This will reconstruct all indices.  If the
4167c478bdstevel@tonic-gate  ** upgrade fails for any reason (ex: out of disk space, database
4177c478bdstevel@tonic-gate  ** is read only, interrupt received, etc.) then fail the init.
4187c478bdstevel@tonic-gate  */
4197c478bdstevel@tonic-gate  if( rc==SQLITE_OK && db->file_format<3 ){
4207c478bdstevel@tonic-gate    char *zErr = 0;
4217c478bdstevel@tonic-gate    InitData initData;
4227c478bdstevel@tonic-gate    int meta[SQLITE_N_BTREE_META];
4237c478bdstevel@tonic-gate
4247c478bdstevel@tonic-gate    db->magic = SQLITE_MAGIC_OPEN;
4257c478bdstevel@tonic-gate    initData.db = db;
4267c478bdstevel@tonic-gate    initData.pzErrMsg = &zErr;
4277c478bdstevel@tonic-gate    db->file_format = 3;
4287c478bdstevel@tonic-gate    rc = sqlite_exec(db,
4297c478bdstevel@tonic-gate      "BEGIN; SELECT name FROM sqlite_master WHERE type='table';",
4307c478bdstevel@tonic-gate      upgrade_3_callback,
4317c478bdstevel@tonic-gate      &initData,
4327c478bdstevel@tonic-gate      &zErr);
4337c478bdstevel@tonic-gate    if( rc==SQLITE_OK ){
4347c478bdstevel@tonic-gate      sqliteBtreeGetMeta(db->aDb[0].pBt, meta);
4357c478bdstevel@tonic-gate      meta[2] = 4;
4367c478bdstevel@tonic-gate      sqliteBtreeUpdateMeta(db->aDb[0].pBt, meta);
4377c478bdstevel@tonic-gate      sqlite_exec(db, "COMMIT", 0, 0, 0);
4387c478bdstevel@tonic-gate    }
4397c478bdstevel@tonic-gate    if( rc!=SQLITE_OK ){
4407c478bdstevel@tonic-gate      sqliteSetString(pzErrMsg,
4417c478bdstevel@tonic-gate        "unable to upgrade database to the version 2.6 format",
4427c478bdstevel@tonic-gate        zErr ? ": " : 0, zErr, (char*)0);
4437c478bdstevel@tonic-gate    }
4447c478bdstevel@tonic-gate    sqlite_freemem(zErr);
4457c478bdstevel@tonic-gate  }
4467c478bdstevel@tonic-gate
4477c478bdstevel@tonic-gate  if( rc!=SQLITE_OK ){
4487c478bdstevel@tonic-gate    db->flags &= ~SQLITE_Initialized;
4497c478bdstevel@tonic-gate  }
4507c478bdstevel@tonic-gate  return rc;
4517c478bdstevel@tonic-gate}
4527c478bdstevel@tonic-gate
4537c478bdstevel@tonic-gate/*
4547c478bdstevel@tonic-gate** The version of the library
4557c478bdstevel@tonic-gate*/
4567c478bdstevel@tonic-gateconst char rcsid[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $";
4577c478bdstevel@tonic-gateconst char sqlite_version[] = SQLITE_VERSION;
4587c478bdstevel@tonic-gate
4597c478bdstevel@tonic-gate/*
4607c478bdstevel@tonic-gate** Does the library expect data to be encoded as UTF-8 or iso8859?  The
4617c478bdstevel@tonic-gate** following global constant always lets us know.
4627c478bdstevel@tonic-gate*/
4637c478bdstevel@tonic-gate#ifdef SQLITE_UTF8
4647c478bdstevel@tonic-gateconst char sqlite_encoding[] = "UTF-8";
4657c478bdstevel@tonic-gate#else
4667c478bdstevel@tonic-gateconst char sqlite_encoding[] = "iso8859";
4677c478bdstevel@tonic-gate#endif
4687c478bdstevel@tonic-gate
4697c478bdstevel@tonic-gate/*
4707c478bdstevel@tonic-gate** Open a new SQLite database.  Construct an "sqlite" structure to define
4717c478bdstevel@tonic-gate** the state of this database and return a pointer to that structure.
4727c478bdstevel@tonic-gate**
4737c478bdstevel@tonic-gate** An attempt is made to initialize the in-memory data structures that
4747c478bdstevel@tonic-gate** hold the database schema.  But if this fails (because the schema file
4757c478bdstevel@tonic-gate** is locked) then that step is deferred until the first call to
4767c478bdstevel@tonic-gate** sqlite_exec().
4777c478bdstevel@tonic-gate*/
4787c478bdstevel@tonic-gatesqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
4797c478bdstevel@tonic-gate  sqlite *db;
4807c478bdstevel@tonic-gate  int rc, i;
4817c478bdstevel@tonic-gate
4827c478bdstevel@tonic-gate  /* Allocate the sqlite data structure */
4837c478bdstevel@tonic-gate  db = sqliteMalloc( sizeof(sqlite) );
4847c478bdstevel@tonic-gate  if( pzErrMsg ) *pzErrMsg = 0;
4857c478bdstevel@tonic-gate  if( db==0 ) goto no_mem_on_open;
4867c478bdstevel@tonic-gate  db->onError = OE_Default;
4877c478bdstevel@tonic-gate  db->priorNewRowid = 0;
4887c478bdstevel@tonic-gate  db->magic = SQLITE_MAGIC_BUSY;
4897c478bdstevel@tonic-gate  db->nDb = 2;
4907c478bdstevel@tonic-gate  db->aDb = db->aDbStatic;
4917c478bdstevel@tonic-gate  /* db->flags |= SQLITE_ShortColNames; */
4927c478bdstevel@tonic-gate  sqliteHashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
4937c478bdstevel@tonic-gate  for(i=0; i<db->nDb; i++){
4947c478bdstevel@tonic-gate    sqliteHashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
4957c478bdstevel@tonic-gate    sqliteHashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
4967c478bdstevel@tonic-gate    sqliteHashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
4977c478bdstevel@tonic-gate    sqliteHashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
4987c478bdstevel@tonic-gate  }
4997c478bdstevel@tonic-gate
5007c478bdstevel@tonic-gate  /* Open the backend database driver */
5017c478bdstevel@tonic-gate  if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
5027c478bdstevel@tonic-gate    db->temp_store = 2;
5037c478bdstevel@tonic-gate  }
5047c478bdstevel@tonic-gate  rc = sqliteBtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
5057c478bdstevel@tonic-gate  if( rc!=SQLITE_OK ){
5067c478bdstevel@tonic-gate    switch( rc ){
5077c478bdstevel@tonic-gate      default: {
5087c478bdstevel@tonic-gate        sqliteSetString(pzErrMsg, "unable to open database: ",
5097c478bdstevel@tonic-gate           zFilename, (char*)0);
5107c478bdstevel@tonic-gate      }
5117c478bdstevel@tonic-gate    }
5127c478bdstevel@tonic-gate    sqliteFree(db);
5137c478bdstevel@tonic-gate    sqliteStrRealloc(pzErrMsg);
5147c478bdstevel@tonic-gate    return 0;
5157c478bdstevel@tonic-gate  }
5167c478bdstevel@tonic-gate  db->aDb[0].zName = "main";
5177c478bdstevel@tonic-gate  db->aDb[1].zName = "temp";
5187c478bdstevel@tonic-gate
5197c478bdstevel@tonic-gate  /* Attempt to read the schema */
5207c478bdstevel@tonic-gate  sqliteRegisterBuiltinFunctions(db);
5217c478bdstevel@tonic-gate  rc = sqliteInit(db, pzErrMsg);
5227c478bdstevel@tonic-gate  db->magic = SQLITE_MAGIC_OPEN;
5237c478bdstevel@tonic-gate  if( sqlite_malloc_failed ){
5247c478bdstevel@tonic-gate    sqlite_close(db);
5257c478bdstevel@tonic-gate    goto no_mem_on_open;
5267c478bdstevel@tonic-gate  }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
5277c478bdstevel@tonic-gate    sqlite_close(db);
5287c478bdstevel@tonic-gate    sqliteStrRealloc(pzErrMsg);
5297c478bdstevel@tonic-gate    return 0;
5307c478bdstevel@tonic-gate  }else if( pzErrMsg ){
5317c478bdstevel@tonic-gate    sqliteFree(*pzErrMsg);
5327c478bdstevel@tonic-gate    *pzErrMsg = 0;
5337c478bdstevel@tonic-gate  }
5347c478bdstevel@tonic-gate
5357c478bdstevel@tonic-gate  /* Return a pointer to the newly opened database structure */
5367c478bdstevel@tonic-gate  return db;
5377c478bdstevel@tonic-gate
5387c478bdstevel@tonic-gateno_mem_on_open:
5397c478bdstevel@tonic-gate  sqliteSetString(pzErrMsg, "out of memory", (char*)0);
5407c478bdstevel@tonic-gate  sqliteStrRealloc(pzErrMsg);
5417c478bdstevel@tonic-gate  return 0;
5427c478bdstevel@tonic-gate}
5437c478bdstevel@tonic-gate
5447c478bdstevel@tonic-gate/*
5457c478bdstevel@tonic-gate** Return the ROWID of the most recent insert
5467c478bdstevel@tonic-gate*/
5477c478bdstevel@tonic-gateint sqlite_last_insert_rowid(sqlite *db){
5487c478bdstevel@tonic-gate  return db->lastRowid;
5497c478bdstevel@tonic-gate}
5507c478bdstevel@tonic-gate
5517c478bdstevel@tonic-gate/*
5527c478bdstevel@tonic-gate** Return the number of changes in the most recent call to sqlite_exec().
5537c478bdstevel@tonic-gate*/
5547c478bdstevel@tonic-gateint sqlite_changes(sqlite *db){
5557c478bdstevel@tonic-gate  return db->nChange;
5567c478bdstevel@tonic-gate}
5577c478bdstevel@tonic-gate
5587c478bdstevel@tonic-gate/*
5597c478bdstevel@tonic-gate** Return the number of changes produced by the last INSERT, UPDATE, or
5607c478bdstevel@tonic-gate** DELETE statement to complete execution. The count does not include
5617c478bdstevel@tonic-gate** changes due to SQL statements executed in trigger programs that were
5627c478bdstevel@tonic-gate** triggered by that statement
5637c478bdstevel@tonic-gate*/
5647c478bdstevel@tonic-gateint sqlite_last_statement_changes(sqlite *db){
5657c478bdstevel@tonic-gate  return db->lsChange;
5667c478bdstevel@tonic-gate}
5677c478bdstevel@tonic-gate
5687c478bdstevel@tonic-gate/*
5697c478bdstevel@tonic-gate** Close an existing SQLite database
5707c478bdstevel@tonic-gate*/
5717c478bdstevel@tonic-gatevoid sqlite_close(sqlite *db){
5727c478bdstevel@tonic-gate  HashElem *i;
5737c478bdstevel@tonic-gate  int j;
5747c478bdstevel@tonic-gate  db->want_to_close = 1;
5757c478bdstevel@tonic-gate  if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){
5767c478bdstevel@tonic-gate    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
5777c478bdstevel@tonic-gate    return;
5787c478bdstevel@tonic-gate  }
5797c478bdstevel@tonic-gate  db->magic = SQLITE_MAGIC_CLOSED;
5807c478bdstevel@tonic-gate  for(j=0; j<db->nDb; j++){
5817c478bdstevel@tonic-gate    struct Db *pDb = &db->aDb[j];
5827c478bdstevel@tonic-gate    if( pDb->pBt ){
5837c478bdstevel@tonic-gate      sqliteBtreeClose(pDb->pBt);
5847c478bdstevel@tonic-gate      pDb->pBt = 0;
5857c478bdstevel@tonic-gate    }
5867c478bdstevel@tonic-gate  }
5877c478bdstevel@tonic-gate  sqliteResetInternalSchema(db, 0);
5887c478bdstevel@tonic-gate  assert( db->nDb<=2 );
5897c478bdstevel@tonic-gate  assert( db->aDb==db->aDbStatic );
5907c478bdstevel@tonic-gate  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
5917c478bdstevel@tonic-gate    FuncDef *pFunc, *pNext;
5927c478bdstevel@tonic-gate    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
5937c478bdstevel@tonic-gate      pNext = pFunc->pNext;
5947c478bdstevel@tonic-gate      sqliteFree(pFunc);
5957c478bdstevel@tonic-gate    }
5967c478bdstevel@tonic-gate  }
5977c478bdstevel@tonic-gate  sqliteHashClear(&db->aFunc);
5987c478bdstevel@tonic-gate  sqliteFree(db);
5997c478bdstevel@tonic-gate}
6007c478bdstevel@tonic-gate
6017c478bdstevel@tonic-gate/*
6027c478bdstevel@tonic-gate** Rollback all database files.
6037c478bdstevel@tonic-gate*/
6047c478bdstevel@tonic-gatevoid sqliteRollbackAll(sqlite *db){
6057c478bdstevel@tonic-gate  int i;
6067c478bdstevel@tonic-gate  for(i=0; i<db->nDb; i++){
6077c478bdstevel@tonic-gate    if( db->aDb[i].pBt ){
6087c478bdstevel@tonic-gate      sqliteBtreeRollback(db->aDb[i].pBt);
6097c478bdstevel@tonic-gate      db->aDb[i].inTrans = 0;
6107c478bdstevel@tonic-gate    }
6117c478bdstevel@tonic-gate  }
6127c478bdstevel@tonic-gate  sqliteResetInternalSchema(db, 0);
6137c478bdstevel@tonic-gate  /* sqliteRollbackInternalChanges(db); */
6147c478bdstevel@tonic-gate}
6157c478bdstevel@tonic-gate
6167c478bdstevel@tonic-gate/*
6177c478bdstevel@tonic-gate** Execute SQL code.  Return one of the SQLITE_ success/failure
6187c478bdstevel@tonic-gate** codes.  Also write an error message into memory obtained from
6197c478bdstevel@tonic-gate** malloc() and make *pzErrMsg point to that message.
6207c478bdstevel@tonic-gate**
6217c478bdstevel@tonic-gate** If the SQL is a query, then for each row in the query result
6227c478bdstevel@tonic-gate** the xCallback() function is called.  pArg becomes the first
6237c478bdstevel@tonic-gate** argument to xCallback().  If xCallback=NULL then no callback
6247c478bdstevel@tonic-gate** is invoked, even for queries.
6257c478bdstevel@tonic-gate*/
6267c478bdstevel@tonic-gateint sqlite_exec(
6277c478bdstevel@tonic-gate  sqlite *db,                 /* The database on which the SQL executes */
6287c478bdstevel@tonic-gate  const char *zSql,           /* The SQL to be executed */
6297c478bdstevel@tonic-gate  sqlite_callback xCallback,  /* Invoke this callback routine */
6307c478bdstevel@tonic-gate  void *pArg,                 /* First argument to xCallback() */
6317c478bdstevel@tonic-gate  char **pzErrMsg             /* Write error messages here */
6327c478bdstevel@tonic-gate){
6337c478bdstevel@tonic-gate  int rc = SQLITE_OK;
6347c478bdstevel@tonic-gate  const char *zLeftover;
6357c478bdstevel@tonic-gate  sqlite_vm *pVm;
6367c478bdstevel@tonic-gate  int nRetry = 0;
6377c478bdstevel@tonic-gate  int nChange = 0;
6387c478bdstevel@tonic-gate  int nCallback;
6397c478bdstevel@tonic-gate
6407c478bdstevel@tonic-gate  if( zSql==0 ) return SQLITE_OK;
6417c478bdstevel@tonic-gate  while( rc==SQLITE_OK && zSql[0] ){
6427c478bdstevel@tonic-gate    pVm = 0;
6437c478bdstevel@tonic-gate    rc = sqlite_compile(db, zSql, &zLeftover, &pVm, pzErrMsg);
6447c478bdstevel@tonic-gate    if( rc!=SQLITE_OK ){
6457c478bdstevel@tonic-gate      assert( pVm==0 || sqlite_malloc_failed );
6467c478bdstevel@tonic-gate      return rc;
6477c478bdstevel@tonic-gate    }
6487c478bdstevel@tonic-gate    if( pVm==0 ){
6497c478bdstevel@tonic-gate      /* This happens if the zSql input contained only whitespace */
6507c478bdstevel@tonic-gate      break;
6517c478bdstevel@tonic-gate    }
6527c478bdstevel@tonic-gate    db->nChange += nChange;
6537c478bdstevel@tonic-gate    nCallback = 0;
6547c478bdstevel@tonic-gate    while(1){
6557c478bdstevel@tonic-gate      int nArg;
6567c478bdstevel@tonic-gate      char **azArg, **azCol;
6577c478bdstevel@tonic-gate      rc = sqlite_step(pVm, &nArg, (const char***)&azArg,(const char***)&azCol);
6587c478bdstevel@tonic-gate      if( rc==SQLITE_ROW ){
6597c478bdstevel@tonic-gate        if( xCallback!=0 && xCallback(pArg, nArg, azArg, azCol) ){
6607c478bdstevel@tonic-gate          sqlite_finalize(pVm, 0);
6617c478bdstevel@tonic-gate          return SQLITE_ABORT;
6627c478bdstevel@tonic-gate        }
6637c478bdstevel@tonic-gate        nCallback++;
6647c478bdstevel@tonic-gate      }else{
6657c478bdstevel@tonic-gate        if( rc==SQLITE_DONE && nCallback==0
6667c478bdstevel@tonic-gate          && (db->flags & SQLITE_NullCallback)!=0 && xCallback!=0 ){
6677c478bdstevel@tonic-gate          xCallback(pArg, nArg, azArg, azCol);
6687c478bdstevel@tonic-gate        }
6697c478bdstevel@tonic-gate        rc = sqlite_finalize(pVm, pzErrMsg);
6707c478bdstevel@tonic-gate        if( rc==SQLITE_SCHEMA && nRetry<2 ){
6717c478bdstevel@tonic-gate          nRetry++;
6727c478bdstevel@tonic-gate          rc = SQLITE_OK;
6737c478bdstevel@tonic-gate          break;
6747c478bdstevel@tonic-gate        }
6757c478bdstevel@tonic-gate        if( db->pVdbe==0 ){
6767c478bdstevel@tonic-gate          nChange = db->nChange;
6777c478bdstevel@tonic-gate        }
6787c478bdstevel@tonic-gate        nRetry = 0;
6797c478bdstevel@tonic-gate        zSql = zLeftover;
6807c478bdstevel@tonic-gate        while( isspace(zSql[0]) ) zSql++;
6817c478bdstevel@tonic-gate        break;
6827c478bdstevel@tonic-gate      }
6837c478bdstevel@tonic-gate    }
6847c478bdstevel@tonic-gate  }
6857c478bdstevel@tonic-gate  return rc;
6867c478bdstevel@tonic-gate}
6877c478bdstevel@tonic-gate
6887c478bdstevel@tonic-gate
6897c478bdstevel@tonic-gate/*
6907c478bdstevel@tonic-gate** Compile a single statement of SQL into a virtual machine.  Return one
6917c478bdstevel@tonic-gate** of the SQLITE_ success/failure codes.  Also write an error message into
6927c478bdstevel@tonic-gate** memory obtained from malloc() and make *pzErrMsg point to that message.
6937c478bdstevel@tonic-gate*/
6947c478bdstevel@tonic-gateint sqlite_compile(
6957c478bdstevel@tonic-gate  sqlite *db,                 /* The database on which the SQL executes */
6967c478bdstevel@tonic-gate  const char *zSql,           /* The SQL to be executed */
6977c478bdstevel@tonic-gate  const char **pzTail,        /* OUT: Next statement after the first */
6987c478bdstevel@tonic-gate  sqlite_vm **ppVm,           /* OUT: The virtual machine */
6997c478bdstevel@tonic-gate  char **pzErrMsg             /* OUT: Write error messages here */
7007c478bdstevel@tonic-gate){
7017c478bdstevel@tonic-gate  Parse sParse;
7027c478bdstevel@tonic-gate
7037c478bdstevel@tonic-gate  if( pzErrMsg ) *pzErrMsg = 0;
7047c478bdstevel@tonic-gate  if( sqliteSafetyOn(db) ) goto exec_misuse;
7057c478bdstevel@tonic-gate  if( !db->init.busy ){
7067c478bdstevel@tonic-gate    if( (db->flags & SQLITE_Initialized)==0 ){
7077c478bdstevel@tonic-gate      int rc, cnt = 1;
7087c478bdstevel@tonic-gate      while( (rc = sqliteInit(db, pzErrMsg))==SQLITE_BUSY
7097c478bdstevel@tonic-gate         && db->xBusyCallback
7107c478bdstevel@tonic-gate         && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
7117c478bdstevel@tonic-gate      if( rc!=SQLITE_OK ){
7127c478bdstevel@tonic-gate        sqliteStrRealloc(pzErrMsg);
7137c478bdstevel@tonic-gate        sqliteSafetyOff(db);
7147c478bdstevel@tonic-gate        return rc;
7157c478bdstevel@tonic-gate      }
7167c478bdstevel@tonic-gate      if( pzErrMsg ){
7177c478bdstevel@tonic-gate        sqliteFree(*pzErrMsg);
7187c478bdstevel@tonic-gate        *pzErrMsg = 0;
7197c478bdstevel@tonic-gate      }
7207c478bdstevel@tonic-gate    }
7217c478bdstevel@tonic-gate    if( db->file_format<3 ){
7227c478bdstevel@tonic-gate      sqliteSafetyOff(db);
7237c478bdstevel@tonic-gate      sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0);
7247c478bdstevel@tonic-gate      return SQLITE_ERROR;
7257c478bdstevel@tonic-gate    }
7267c478bdstevel@tonic-gate  }
7277c478bdstevel@tonic-gate  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );
7287c478bdstevel@tonic-gate  if( db->pVdbe==0 ){ db->nChange = 0; }
7297c478bdstevel@tonic-gate  memset(&sParse, 0, sizeof(sParse));
7307c478bdstevel@tonic-gate  sParse.db = db;
7317c478bdstevel@tonic-gate  sqliteRunParser(&sParse, zSql, pzErrMsg);
7327c478bdstevel@tonic-gate  if( db->xTrace && !db->init.busy ){
7337c478bdstevel@tonic-gate    /* Trace only the statment that was compiled.
7347c478bdstevel@tonic-gate    ** Make a copy of that part of the SQL string since zSQL is const
7357c478bdstevel@tonic-gate    ** and we must pass a zero terminated string to the trace function
7367c478bdstevel@tonic-gate    ** The copy is unnecessary if the tail pointer is pointing at the
7377c478bdstevel@tonic-gate    ** beginnig or end of the SQL string.
7387c478bdstevel@tonic-gate    */
7397c478bdstevel@tonic-gate    if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){
7407c478bdstevel@tonic-gate      char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql);
7417c478bdstevel@tonic-gate      if( tmpSql ){
7427c478bdstevel@tonic-gate        db->xTrace(db->pTraceArg, tmpSql);
7437c478bdstevel@tonic-gate        free(tmpSql);
7447c478bdstevel@tonic-gate      }else{
7457c478bdstevel@tonic-gate        /* If a memory error occurred during the copy,
7467c478bdstevel@tonic-gate        ** trace entire SQL string and fall through to the
7477c478bdstevel@tonic-gate        ** sqlite_malloc_failed test to report the error.
7487c478bdstevel@tonic-gate        */
7497c478bdstevel@tonic-gate        db->xTrace(db->pTraceArg, zSql);
7507c478bdstevel@tonic-gate      }
7517c478bdstevel@tonic-gate    }else{
7527c478bdstevel@tonic-gate      db->xTrace(db->pTraceArg, zSql);
7537c478bdstevel@tonic-gate    }
7547c478bdstevel@tonic-gate  }
7557c478bdstevel@tonic-gate  if( sqlite_malloc_failed ){
7567c478bdstevel@tonic-gate    sqliteSetString(pzErrMsg, "out of memory", (char*)0);
7577c478bdstevel@tonic-gate    sParse.rc = SQLITE_NOMEM;
7587c478bdstevel@tonic-gate    sqliteRollbackAll(db);
7597c478bdstevel@tonic-gate    sqliteResetInternalSchema(db, 0);
7607c478bdstevel@tonic-gate    db->flags &= ~SQLITE_InTrans;
7617c478bdstevel@tonic-gate  }
7627c478bdstevel@tonic-gate  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
7637c478bdstevel@tonic-gate  if( sParse.rc!=SQLITE_OK && pzErrMsg && *pzErrMsg==0 ){
7647c478bdstevel@tonic-gate    sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), (char*)0);
7657c478bdstevel@tonic-gate  }
7667c478bdstevel@tonic-gate  sqliteStrRealloc(pzErrMsg);
7677c478bdstevel@tonic-gate  if( sParse.rc==SQLITE_SCHEMA ){
7687c478bdstevel@tonic-gate    sqliteResetInternalSchema(db, 0);
7697c478bdstevel@tonic-gate  }
7707c478bdstevel@tonic-gate  assert( ppVm );
7717c478bdstevel@tonic-gate  *ppVm = (sqlite_vm*)sParse.pVdbe;
7727c478bdstevel@tonic-gate  if( pzTail ) *pzTail = sParse.zTail;
7737c478bdstevel@tonic-gate  if( sqliteSafetyOff(db) ) goto exec_misuse;
7747c478bdstevel@tonic-gate  return sParse.rc;
7757c478bdstevel@tonic-gate
7767c478bdstevel@tonic-gateexec_misuse:
7777c478bdstevel@tonic-gate  if( pzErrMsg ){
7787c478bdstevel@tonic-gate    *pzErrMsg = 0;
7797c478bdstevel@tonic-gate    sqliteSetString(pzErrMsg, sqlite_error_string(SQLITE_MISUSE), (char*)0);
7807c478bdstevel@tonic-gate    sqliteStrRealloc(pzErrMsg);
7817c478bdstevel@tonic-gate  }
7827c478bdstevel@tonic-gate  return SQLITE_MISUSE;
7837c478bdstevel@tonic-gate}
7847c478bdstevel@tonic-gate
7857c478bdstevel@tonic-gate
7867c478bdstevel@tonic-gate/*
7877c478bdstevel@tonic-gate** The following routine destroys a virtual machine that is created by
7887c478bdstevel@tonic-gate** the sqlite_compile() routine.
7897c478bdstevel@tonic-gate**
7907c478bdstevel@tonic-gate** The integer returned is an SQLITE_ success/failure code that describes
7917c478bdstevel@tonic-gate** the result of executing the virtual machine.  An error message is
7927c478bdstevel@tonic-gate** written into memory obtained from malloc and *pzErrMsg is made to
7937c478bdstevel@tonic-gate** point to that error if pzErrMsg is not NULL.  The calling routine
7947c478bdstevel@tonic-gate** should use sqlite_freemem() to delete the message when it has finished
7957c478bdstevel@tonic-gate** with it.
7967c478bdstevel@tonic-gate*/
7977c478bdstevel@tonic-gateint sqlite_finalize(
7987c478bdstevel@tonic-gate  sqlite_vm *pVm,            /* The virtual machine to be destroyed */
7997c478bdstevel@tonic-gate  char **pzErrMsg            /* OUT: Write error messages here */
8007c478bdstevel@tonic-gate){
8017c478bdstevel@tonic-gate  int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
8027c478bdstevel@tonic-gate  sqliteStrRealloc(pzErrMsg);
8037c478bdstevel@tonic-gate  return rc;
8047c478bdstevel@tonic-gate}
8057c478bdstevel@tonic-gate
8067c478bdstevel@tonic-gate/*
8077c478bdstevel@tonic-gate** Terminate the current execution of a virtual machine then
8087c478bdstevel@tonic-gate** reset the virtual machine back to its starting state so that it
8097c478bdstevel@tonic-gate** can be reused.  Any error message resulting from the prior execution
8107c478bdstevel@tonic-gate** is written into *pzErrMsg.  A success code from the prior execution
8117c478bdstevel@tonic-gate** is returned.
8127c478bdstevel@tonic-gate*/
8137c478bdstevel@tonic-gateint sqlite_reset(
8147c478bdstevel@tonic-gate  sqlite_vm *pVm,            /* The virtual machine to be destroyed */
8157c478bdstevel@tonic-gate  char **pzErrMsg            /* OUT: Write error messages here */
8167c478bdstevel@tonic-gate){
8177c478bdstevel@tonic-gate  int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg);
8187c478bdstevel@tonic-gate  sqliteVdbeMakeReady((Vdbe*)pVm, -1, 0);
8197c478bdstevel@tonic-gate  sqliteStrRealloc(pzErrMsg);
8207c478bdstevel@tonic-gate  return rc;
8217c478bdstevel@tonic-gate}
8227c478bdstevel@tonic-gate
8237c478bdstevel@tonic-gate/*
8247c478bdstevel@tonic-gate** Return a static string that describes the kind of error specified in the
8257c478bdstevel@tonic-gate** argument.
8267c478bdstevel@tonic-gate*/
8277c478bdstevel@tonic-gateconst char *sqlite_error_string(int rc){
8287c478bdstevel@tonic-gate  const char *z;
8297c478bdstevel@tonic-gate  switch( rc ){
8307c478bdstevel@tonic-gate    case SQLITE_OK:         z = "not an error";                          break;
8317c478bdstevel@tonic-gate    case SQLITE_ERROR:      z = "SQL logic error or missing database";   break;
8327c478bdstevel@tonic-gate    case SQLITE_INTERNAL:   z = "internal SQLite implementation flaw";   break;
8337c478bdstevel@tonic-gate    case SQLITE_PERM:       z = "access permission denied";              break;
8347c478bdstevel@tonic-gate    case SQLITE_ABORT:      z = "callback requested query abort";        break;
8357c478bdstevel@tonic-gate    case SQLITE_BUSY:       z = "database is locked";                    break;
8367c478bdstevel@tonic-gate    case SQLITE_LOCKED:     z = "database table is locked";              break;
8377c478bdstevel@tonic-gate    case SQLITE_NOMEM:      z = "out of memory";                         break;
8387c478bdstevel@tonic-gate    case SQLITE_READONLY:   z = "attempt to write a readonly database";  break;
8397c478bdstevel@tonic-gate    case SQLITE_INTERRUPT:  z = "interrupted";                           break;
8407c478bdstevel@tonic-gate    case SQLITE_IOERR:      z = "disk I/O error";                        break;
8417c478bdstevel@tonic-gate    case SQLITE_CORRUPT:    z = "database disk image is malformed";      break;
8427c478bdstevel@tonic-gate    case SQLITE_NOTFOUND:   z = "table or record not found";             break;
8437c478bdstevel@tonic-gate    case SQLITE_FULL:       z = "database is full";                      break;
8447c478bdstevel@tonic-gate    case SQLITE_CANTOPEN:   z = "unable to open database file";          break;
8457c478bdstevel@tonic-gate    case SQLITE_PROTOCOL:   z = "database locking protocol failure";     break;
8467c478bdstevel@tonic-gate    case SQLITE_EMPTY:      z = "table contains no data";                break;
8477c478bdstevel@tonic-gate    case SQLITE_SCHEMA:     z = "database schema has changed";           break;
8487c478bdstevel@tonic-gate    case SQLITE_TOOBIG:     z = "too much data for one table row";       break;
8497c478bdstevel@tonic-gate    case SQLITE_CONSTRAINT: z = "constraint failed";                     break;
8507c478bdstevel@tonic-gate    case SQLITE_MISMATCH:   z = "datatype mismatch";                     break;
8517c478bdstevel@tonic-gate    case SQLITE_MISUSE:     z = "library routine called out of sequence";break;
8527c478bdstevel@tonic-gate    case SQLITE_NOLFS:      z = "kernel lacks large file support";       break;
8537c478bdstevel@tonic-gate    case SQLITE_AUTH:       z = "authorization denied";                  break;
8547c478bdstevel@tonic-gate    case SQLITE_FORMAT:     z = "auxiliary database format error";       break;
8557c478bdstevel@tonic-gate    case SQLITE_RANGE:      z = "bind index out of range";               break;
8567c478bdstevel@tonic-gate    case SQLITE_NOTADB:     z = "file is encrypted or is not a database";break;
8577c478bdstevel@tonic-gate    default:                z = "unknown error";                         break;
8587c478bdstevel@tonic-gate  }
8597c478bdstevel@tonic-gate  return z;
8607c478bdstevel@tonic-gate}
8617c478bdstevel@tonic-gate
8627c478bdstevel@tonic-gate/*
8637c478bdstevel@tonic-gate** This routine implements a busy callback that sleeps and tries
8647c478bdstevel@tonic-gate** again until a timeout value is reached.  The timeout value is
8657c478bdstevel@tonic-gate** an integer number of milliseconds passed in as the first
8667c478bdstevel@tonic-gate** argument.
8677c478bdstevel@tonic-gate*/
8687c478bdstevel@tonic-gatestatic int sqliteDefaultBusyCallback(
8697c478bdstevel@tonic-gate void *Timeout,           /* Maximum amount of time to wait */
8707c478bdstevel@tonic-gate const char *NotUsed,     /* The name of the table that is busy */
8717c478bdstevel@tonic-gate int count                /* Number of times table has been busy */
8727c478bdstevel@tonic-gate){
8737c478bdstevel@tonic-gate#if SQLITE_MIN_SLEEP_MS==1
8747c478bdstevel@tonic-gate  static const char delays[] =
8757c478bdstevel@tonic-gate     { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50,  50, 100};
8767c478bdstevel@tonic-gate  static const short int totals[] =
8777c478bdstevel@tonic-gate     { 0, 1, 3,  8, 18, 33, 53, 78, 103, 128, 178, 228, 287};
8787c478bdstevel@tonic-gate# define NDELAY (sizeof(delays)/sizeof(delays[0]))
8797c478bdstevel@tonic-gate  int timeout = (int)(long)Timeout;
8807c478bdstevel@tonic-gate  int delay, prior;
8817c478bdstevel@tonic-gate
8827c478bdstevel@tonic-gate  if( count <= NDELAY ){
8837c478bdstevel@tonic-gate    delay = delays[count-1];
8847c478bdstevel@tonic-gate    prior = totals[count-1];
8857c478bdstevel@tonic-gate  }else{
8867c478bdstevel@tonic-gate    delay = delays[NDELAY-1];
8877c478bdstevel@tonic-gate    prior = totals[NDELAY-1] + delay*(count-NDELAY-1);
8887c478bdstevel@tonic-gate  }
8897c478bdstevel@tonic-gate  if( prior + delay > timeout ){
8907c478bdstevel@tonic-gate    delay = timeout - prior;
8917c478bdstevel@tonic-gate    if( delay<=0 ) return 0;
8927c478bdstevel@tonic-gate  }
8937c478bdstevel@tonic-gate  sqliteOsSleep(delay);
8947c478bdstevel@tonic-gate  return 1;
8957c478bdstevel@tonic-gate#else
8967c478bdstevel@tonic-gate  int timeout = (int)(long)Timeout;
8977c478bdstevel@tonic-gate  if( (count+1)*1000 > timeout ){
8987c478bdstevel@tonic-gate    return 0;
8997c478bdstevel@tonic-gate  }
9007c478bdstevel@tonic-gate  sqliteOsSleep(1000);
9017c478bdstevel@tonic-gate  return 1;
9027c478bdstevel@tonic-gate#endif
9037c478bdstevel@tonic-gate}
9047c478bdstevel@tonic-gate
9057c478bdstevel@tonic-gate/*
9067c478bdstevel@tonic-gate** This routine sets the busy callback for an Sqlite database to the
9077c478bdstevel@tonic-gate** given callback function with the given argument.
9087c478bdstevel@tonic-gate*/
9097c478bdstevel@tonic-gatevoid sqlite_busy_handler(
9107c478bdstevel@tonic-gate  sqlite *db,
9117c478bdstevel@tonic-gate  int (*xBusy)(void*,const char*,int),
9127c478bdstevel@tonic-gate  void *pArg
9137c478bdstevel@tonic-gate){
9147c478bdstevel@tonic-gate  db->xBusyCallback = xBusy;
9157c478bdstevel@tonic-gate  db->pBusyArg = pArg;
9167c478bdstevel@tonic-gate}
9177c478bdstevel@tonic-gate
9187c478bdstevel@tonic-gate#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
9197c478bdstevel@tonic-gate/*
9207c478bdstevel@tonic-gate** This routine sets the progress callback for an Sqlite database to the
9217c478bdstevel@tonic-gate** given callback function with the given argument. The progress callback will
9227c478bdstevel@tonic-gate** be invoked every nOps opcodes.
9237c478bdstevel@tonic-gate*/
9247c478bdstevel@tonic-gatevoid sqlite_progress_handler(
9257c478bdstevel@tonic-gate  sqlite *db,
9267c478bdstevel@tonic-gate  int nOps,
9277c478bdstevel@tonic-gate  int (*xProgress)(void*),
9287c478bdstevel@tonic-gate  void *pArg
9297c478bdstevel@tonic-gate){
9307c478bdstevel@tonic-gate  if( nOps>0 ){
9317c478bdstevel@tonic-gate    db->xProgress = xProgress;
9327c478bdstevel@tonic-gate    db->nProgressOps = nOps;
9337c478bdstevel@tonic-gate    db->pProgressArg = pArg;
9347c478bdstevel@tonic-gate  }else{
9357c478bdstevel@tonic-gate    db->xProgress = 0;
9367c478bdstevel@tonic-gate    db->nProgressOps = 0;
9377c478bdstevel@tonic-gate    db->pProgressArg = 0;
9387c478bdstevel@tonic-gate  }
9397c478bdstevel@tonic-gate}
9407c478bdstevel@tonic-gate#endif
9417c478bdstevel@tonic-gate
9427c478bdstevel@tonic-gate
9437c478bdstevel@tonic-gate/*
9447c478bdstevel@tonic-gate** This routine installs a default busy handler that waits for the
9457c478bdstevel@tonic-gate** specified number of milliseconds before returning 0.
9467c478bdstevel@tonic-gate*/
9477c478bdstevel@tonic-gatevoid sqlite_busy_timeout(sqlite *db, int ms){
9487c478bdstevel@tonic-gate  if( ms>0 ){
9497c478bdstevel@tonic-gate    sqlite_busy_handler(db, sqliteDefaultBusyCallback, (void*)(long)ms);
9507c478bdstevel@tonic-gate  }else{
9517c478bdstevel@tonic-gate    sqlite_busy_handler(db, 0, 0);
9527c478bdstevel@tonic-gate  }
9537c478bdstevel@tonic-gate}
9547c478bdstevel@tonic-gate
9557c478bdstevel@tonic-gate/*
9567c478bdstevel@tonic-gate** Cause any pending operation to stop at its earliest opportunity.
9577c478bdstevel@tonic-gate*/
9587c478bdstevel@tonic-gatevoid sqlite_interrupt(sqlite *db){
9597c478bdstevel@tonic-gate  db->flags |= SQLITE_Interrupt;
9607c478bdstevel@tonic-gate}
9617c478bdstevel@tonic-gate
9627c478bdstevel@tonic-gate/*
9637c478bdstevel@tonic-gate** Windows systems should call this routine to free memory that
9647c478bdstevel@tonic-gate** is returned in the in the errmsg parameter of sqlite_open() when
9657c478bdstevel@tonic-gate** SQLite is a DLL.  For some reason, it does not work to call free()
9667c478bdstevel@tonic-gate** directly.
9677c478bdstevel@tonic-gate**
9687c478bdstevel@tonic-gate** Note that we need to call free() not sqliteFree() here, since every
9697c478bdstevel@tonic-gate** string that is exported from SQLite should have already passed through
9707c478bdstevel@tonic-gate** sqliteStrRealloc().
9717c478bdstevel@tonic-gate*/
9727c478bdstevel@tonic-gatevoid sqlite_freemem(void *p){ free(p); }
9737c478bdstevel@tonic-gate
9747c478bdstevel@tonic-gate/*
9757c478bdstevel@tonic-gate** Windows systems need functions to call to return the sqlite_version
9767c478bdstevel@tonic-gate** and sqlite_encoding strings since they are unable to access constants
9777c478bdstevel@tonic-gate** within DLLs.
9787c478bdstevel@tonic-gate*/
9797c478bdstevel@tonic-gateconst char *sqlite_libversion(void){ return sqlite_version; }
9807c478bdstevel@tonic-gateconst char *sqlite_libencoding(void){ return sqlite_encoding; }
9817c478bdstevel@tonic-gate
9827c478bdstevel@tonic-gate/*
9837c478bdstevel@tonic-gate** Create new user-defined functions.  The sqlite_create_function()
9847c478bdstevel@tonic-gate** routine creates a regular function and sqlite_create_aggregate()
9857c478bdstevel@tonic-gate** creates an aggregate function.
9867c478bdstevel@tonic-gate**
9877c478bdstevel@tonic-gate** Passing a NULL xFunc argument or NULL xStep and xFinalize arguments
9887c478bdstevel@tonic-gate** disables the function.  Calling sqlite_create_function() with the
9897c478bdstevel@tonic-gate** same name and number of arguments as a prior call to
9907c478bdstevel@tonic-gate** sqlite_create_aggregate() disables the prior call to
9917c478bdstevel@tonic-gate** sqlite_create_aggregate(), and vice versa.
9927c478bdstevel@tonic-gate**
9937c478bdstevel@tonic-gate** If nArg is -1 it means that this function will accept any number
9947c478bdstevel@tonic-gate** of arguments, including 0.  The maximum allowed value of nArg is 127.
9957c478bdstevel@tonic-gate*/
9967c478bdstevel@tonic-gateint sqlite_create_function(
9977c478bdstevel@tonic-gate  sqlite *db,          /* Add the function to this database connection */
9987c478bdstevel@tonic-gate  const char *zName,   /* Name of the function to add */
9997c478bdstevel@tonic-gate  int nArg,            /* Number of arguments */
10007c478bdstevel@tonic-gate  void (*xFunc)(sqlite_func*,int,const char**),  /* The implementation */
10017c478bdstevel@tonic-gate  void *pUserData      /* User data */
10027c478bdstevel@tonic-gate){
10037c478bdstevel@tonic-gate  FuncDef *p;
10047c478bdstevel@tonic-gate  int nName;
10057c478bdstevel@tonic-gate  if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
10067c478bdstevel@tonic-gate  if( nArg<-1 || nArg>127 ) return 1;
10077c478bdstevel@tonic-gate  nName = strlen(zName);
10087c478bdstevel@tonic-gate  if( nName>255 ) return 1;
10097c478bdstevel@tonic-gate  p = sqliteFindFunction(db, zName, nName, nArg, 1);
10107c478bdstevel@tonic-gate  if( p==0 ) return 1;
10117c478bdstevel@tonic-gate  p->xFunc = xFunc;
10127c478bdstevel@tonic-gate  p->xStep = 0;
10137c478bdstevel@tonic-gate  p->xFinalize = 0;
10147c478bdstevel@tonic-gate  p->pUserData = pUserData;
10157c478bdstevel@tonic-gate  return 0;
10167c478bdstevel@tonic-gate}
10177c478bdstevel@tonic-gateint sqlite_create_aggregate(
10187c478bdstevel@tonic-gate  sqlite *db,          /* Add the function to this database connection */
10197c478bdstevel@tonic-gate  const char *zName,   /* Name of the function to add */
10207c478bdstevel@tonic-gate  int nArg,            /* Number of arguments */
10217c478bdstevel@tonic-gate  void (*xStep)(sqlite_func*,int,const char**), /* The step function */
10227c478bdstevel@tonic-gate  void (*xFinalize)(sqlite_func*),              /* The finalizer */
10237c478bdstevel@tonic-gate  void *pUserData      /* User data */
10247c478bdstevel@tonic-gate){
10257c478bdstevel@tonic-gate  FuncDef *p;
10267c478bdstevel@tonic-gate  int nName;
10277c478bdstevel@tonic-gate  if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
10287c478bdstevel@tonic-gate  if( nArg<-1 || nArg>127 ) return 1;
10297c478bdstevel@tonic-gate  nName = strlen(zName);
10307c478bdstevel@tonic-gate  if( nName>255 ) return 1;
10317c478bdstevel@tonic-gate  p = sqliteFindFunction(db, zName, nName, nArg, 1);
10327c478bdstevel@tonic-gate  if( p==0 ) return 1;
10337c478bdstevel@tonic-gate  p->xFunc = 0;
10347c478bdstevel@tonic-gate  p->xStep = xStep;
10357c478bdstevel@tonic-gate  p->xFinalize = xFinalize;
10367c478bdstevel@tonic-gate  p->pUserData = pUserData;
10377c478bdstevel@tonic-gate  return 0;
10387c478bdstevel@tonic-gate}
10397c478bdstevel@tonic-gate
10407c478bdstevel@tonic-gate/*
10417c478bdstevel@tonic-gate** Change the datatype for all functions with a given name.  See the
10427c478bdstevel@tonic-gate** header comment for the prototype of this function in sqlite.h for
10437c478bdstevel@tonic-gate** additional information.
10447c478bdstevel@tonic-gate*/
10457c478bdstevel@tonic-gateint sqlite_function_type(sqlite *db, const char *zName, int dataType){
10467c478bdstevel@tonic-gate  FuncDef *p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, strlen(zName));
10477c478bdstevel@tonic-gate  while( p ){
10487c478bdstevel@tonic-gate    p->dataType = dataType;
10497c478bdstevel@tonic-gate    p = p->pNext;
10507c478bdstevel@tonic-gate  }
10517c478bdstevel@tonic-gate  return SQLITE_OK;
10527c478bdstevel@tonic-gate}
10537c478bdstevel@tonic-gate
10547c478bdstevel@tonic-gate/*
10557c478bdstevel@tonic-gate** Register a trace function.  The pArg from the previously registered trace
10567c478bdstevel@tonic-gate** is returned.
10577c478bdstevel@tonic-gate**
10587c478bdstevel@tonic-gate** A NULL trace function means that no tracing is executes.  A non-NULL
10597c478bdstevel@tonic-gate** trace is a pointer to a function that is invoked at the start of each
10607c478bdstevel@tonic-gate** sqlite_exec().
10617c478bdstevel@tonic-gate*/
10627c478bdstevel@tonic-gatevoid *sqlite_trace(sqlite *db, void (*xTrace)(void*,const char*), void *pArg){
10637c478bdstevel@tonic-gate  void *pOld = db->pTraceArg;
10647c478bdstevel@tonic-gate  db->xTrace = xTrace;
10657c478bdstevel@tonic-gate  db->pTraceArg = pArg;
10667c478bdstevel@tonic-gate  return pOld;
10677c478bdstevel@tonic-gate}
10687c478bdstevel@tonic-gate
10697c478bdstevel@tonic-gate/*** EXPERIMENTAL ***
10707c478bdstevel@tonic-gate**
10717c478bdstevel@tonic-gate** Register a function to be invoked when a transaction comments.
10727c478bdstevel@tonic-gate** If either function returns non-zero, then the commit becomes a
10737c478bdstevel@tonic-gate** rollback.
10747c478bdstevel@tonic-gate*/
10757c478bdstevel@tonic-gatevoid *sqlite_commit_hook(
10767c478bdstevel@tonic-gate  sqlite *db,               /* Attach the hook to this database */
10777c478bdstevel@tonic-gate  int (*xCallback)(void*),  /* Function to invoke on each commit */
10787c478bdstevel@tonic-gate  void *pArg                /* Argument to the function */
10797c478bdstevel@tonic-gate){
10807c478bdstevel@tonic-gate  void *pOld = db->pCommitArg;
10817c478bdstevel@tonic-gate  db->xCommitCallback = xCallback;
10827c478bdstevel@tonic-gate  db->pCommitArg = pArg;
10837c478bdstevel@tonic-gate  return pOld;
10847c478bdstevel@tonic-gate}
10857c478bdstevel@tonic-gate
10867c478bdstevel@tonic-gate
10877c478bdstevel@tonic-gate/*
10887c478bdstevel@tonic-gate** This routine is called to create a connection to a database BTree
10897c478bdstevel@tonic-gate** driver.  If zFilename is the name of a file, then that file is
10907c478bdstevel@tonic-gate** opened and used.  If zFilename is the magic name ":memory:" then
10917c478bdstevel@tonic-gate** the database is stored in memory (and is thus forgotten as soon as
10927c478bdstevel@tonic-gate** the connection is closed.)  If zFilename is NULL then the database
10937c478bdstevel@tonic-gate** is for temporary use only and is deleted as soon as the connection
10947c478bdstevel@tonic-gate** is closed.
10957c478bdstevel@tonic-gate**
10967c478bdstevel@tonic-gate** A temporary database can be either a disk file (that is automatically
10977c478bdstevel@tonic-gate** deleted when the file is closed) or a set of red-black trees held in memory,
10987c478bdstevel@tonic-gate** depending on the values of the TEMP_STORE compile-time macro and the
10997c478bdstevel@tonic-gate** db->temp_store variable, according to the following chart:
11007c478bdstevel@tonic-gate**
11017c478bdstevel@tonic-gate**       TEMP_STORE     db->temp_store     Location of temporary database
11027c478bdstevel@tonic-gate**       ----------     --------------     ------------------------------
11037c478bdstevel@tonic-gate**           0               any             file
11047c478bdstevel@tonic-gate**           1                1              file
11057c478bdstevel@tonic-gate**           1                2              memory
11067c478bdstevel@tonic-gate**           1                0              file
11077c478bdstevel@tonic-gate**           2                1              file
11087c478bdstevel@tonic-gate**           2                2              memory
11097c478bdstevel@tonic-gate**           2                0              memory
11107c478bdstevel@tonic-gate**           3               any             memory
11117c478bdstevel@tonic-gate*/
11127c478bdstevel@tonic-gateint sqliteBtreeFactory(
11137c478bdstevel@tonic-gate  const sqlite *db,	    /* Main database when opening aux otherwise 0 */
11147c478bdstevel@tonic-gate  const char *zFilename,    /* Name of the file containing the BTree database */
11157c478bdstevel@tonic-gate  int omitJournal,          /* if TRUE then do not journal this file */
11167c478bdstevel@tonic-gate  int nCache,               /* How many pages in the page cache */
11177c478bdstevel@tonic-gate  Btree **ppBtree){         /* Pointer to new Btree object written here */
11187c478bdstevel@tonic-gate
11197c478bdstevel@tonic-gate  assert( ppBtree != 0);
11207c478bdstevel@tonic-gate
11217c478bdstevel@tonic-gate#ifndef SQLITE_OMIT_INMEMORYDB
11227c478bdstevel@tonic-gate  if( zFilename==0 ){
11237c478bdstevel@tonic-gate    if (TEMP_STORE == 0) {
11247c478bdstevel@tonic-gate      /* Always use file based temporary DB */
11257c478bdstevel@tonic-gate      return sqliteBtreeOpen(0, omitJournal, nCache, ppBtree);
11267c478bdstevel@tonic-gate    } else if (TEMP_STORE == 1 || TEMP_STORE == 2) {
11277c478bdstevel@tonic-gate      /* Switch depending on compile-time and/or runtime settings. */
11287c478bdstevel@tonic-gate      int location = db->temp_store==0 ? TEMP_STORE : db->temp_store;
11297c478bdstevel@tonic-gate
11307c478bdstevel@tonic-gate      if (location == 1) {
11317c478bdstevel@tonic-gate        return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
11327c478bdstevel@tonic-gate      } else {
11337c478bdstevel@tonic-gate        return sqliteRbtreeOpen(0, 0, 0, ppBtree);
11347c478bdstevel@tonic-gate      }
11357c478bdstevel@tonic-gate    } else {
11367c478bdstevel@tonic-gate      /* Always use in-core DB */
11377c478bdstevel@tonic-gate      return sqliteRbtreeOpen(0, 0, 0, ppBtree);
11387c478bdstevel@tonic-gate    }
11397c478bdstevel@tonic-gate  }else if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
11407c478bdstevel@tonic-gate    return sqliteRbtreeOpen(0, 0, 0, ppBtree);
11417c478bdstevel@tonic-gate  }else
11427c478bdstevel@tonic-gate#endif
11437c478bdstevel@tonic-gate  {
11447c478bdstevel@tonic-gate    return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
11457c478bdstevel@tonic-gate  }
11467c478bdstevel@tonic-gate}
1147