From 7be0b0b8dc1030eee1f2eea474a63a431e622a29 Mon Sep 17 00:00:00 2001 From: "vladimir%pobox.com" Date: Tue, 22 Mar 2005 23:10:06 +0000 Subject: [PATCH] Update to SQLite 3.2.0 --- db/sqlite3/src/Makefile.in | 3 +- db/sqlite3/src/alter.c | 550 +++++ db/sqlite3/src/attach.c | 59 +- db/sqlite3/src/auth.c | 7 +- db/sqlite3/src/btree.c | 1847 ++++++++++++--- db/sqlite3/src/btree.h | 27 +- db/sqlite3/src/build.c | 1007 ++++++--- db/sqlite3/src/config.h | 10 +- db/sqlite3/src/date.c | 123 +- db/sqlite3/src/delete.c | 94 +- db/sqlite3/src/expr.c | 1188 ++++++---- db/sqlite3/src/func.c | 102 +- db/sqlite3/src/hash.c | 11 +- db/sqlite3/src/insert.c | 221 +- db/sqlite3/src/keywordhash.h | 96 + db/sqlite3/src/main.c | 179 +- db/sqlite3/src/opcodes.c | 259 +-- db/sqlite3/src/opcodes.h | 257 ++- db/sqlite3/src/os.h | 36 +- db/sqlite3/src/os_unix.c | 100 +- db/sqlite3/src/os_unix.h | 6 + db/sqlite3/src/os_win.c | 34 +- db/sqlite3/src/pager.c | 876 ++++++-- db/sqlite3/src/pager.h | 16 +- db/sqlite3/src/parse.c | 4121 ++++++++++++++++++---------------- db/sqlite3/src/parse.h | 157 +- db/sqlite3/src/pragma.c | 338 ++- db/sqlite3/src/printf.c | 24 +- db/sqlite3/src/select.c | 678 ++++-- db/sqlite3/src/shell.c | 21 +- db/sqlite3/src/sqlite.h.in | 127 +- db/sqlite3/src/sqliteInt.h | 311 ++- db/sqlite3/src/tclsqlite.c | 554 ++++- db/sqlite3/src/tokenize.c | 237 +- db/sqlite3/src/trigger.c | 156 +- db/sqlite3/src/update.c | 111 +- db/sqlite3/src/utf.c | 14 +- db/sqlite3/src/util.c | 82 +- db/sqlite3/src/vacuum.c | 88 +- db/sqlite3/src/vdbe.c | 480 +++- db/sqlite3/src/vdbe.h | 6 +- db/sqlite3/src/vdbeInt.h | 10 +- db/sqlite3/src/vdbeapi.c | 62 +- db/sqlite3/src/vdbeaux.c | 170 +- db/sqlite3/src/vdbemem.c | 87 +- db/sqlite3/src/where.c | 840 ++++--- 46 files changed, 10745 insertions(+), 5037 deletions(-) create mode 100644 db/sqlite3/src/alter.c create mode 100644 db/sqlite3/src/keywordhash.h diff --git a/db/sqlite3/src/Makefile.in b/db/sqlite3/src/Makefile.in index 7b545e02642..1542e210306 100644 --- a/db/sqlite3/src/Makefile.in +++ b/db/sqlite3/src/Makefile.in @@ -48,11 +48,12 @@ LIBRARY_NAME = sqlite3_s MODULE_NAME = sqlite3 FORCE_STATIC_LIB = 1 -VERSION = 3.0.8 +VERSION = 3.2.0 EXPORTS = sqlite3.h CSRCS = \ + alter.c \ attach.c \ auth.c \ btree.c \ diff --git a/db/sqlite3/src/alter.c b/db/sqlite3/src/alter.c new file mode 100644 index 00000000000..d20d91e22f3 --- /dev/null +++ b/db/sqlite3/src/alter.c @@ -0,0 +1,550 @@ +/* +** 2005 February 15 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains C code routines that used to generate VDBE code +** that implements the ALTER TABLE command. +** +** $Id: alter.c,v 1.1 2005-03-22 23:10:06 vladimir%pobox.com Exp $ +*/ +#include "sqliteInt.h" +#include + +/* +** The code in this file only exists if we are not omitting the +** ALTER TABLE logic from the build. +*/ +#ifndef SQLITE_OMIT_ALTERTABLE + + +/* +** This function is used by SQL generated to implement the +** ALTER TABLE command. The first argument is the text of a CREATE TABLE or +** CREATE INDEX command. The second is a table name. The table name in +** the CREATE TABLE or CREATE INDEX statement is replaced with the second +** argument and the result returned. Examples: +** +** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def') +** -> 'CREATE TABLE def(a, b, c)' +** +** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def') +** -> 'CREATE INDEX i ON def(a, b, c)' +*/ +static void renameTableFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char const *zSql = sqlite3_value_text(argv[0]); + unsigned char const *zTableName = sqlite3_value_text(argv[1]); + + int token; + Token tname; + char const *zCsr = zSql; + int len = 0; + char *zRet; + + /* The principle used to locate the table name in the CREATE TABLE + ** statement is that the table name is the first token that is immediatedly + ** followed by a left parenthesis - TK_LP. + */ + if( zSql ){ + do { + /* Store the token that zCsr points to in tname. */ + tname.z = zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and it's length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + } while( token==TK_SPACE ); + assert( len>0 ); + } while( token!=TK_LP ); + + zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, + zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, sqlite3FreeX); + } +} + +#ifndef SQLITE_OMIT_TRIGGER +/* This function is used by SQL generated to implement the ALTER TABLE +** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER +** statement. The second is a table name. The table name in the CREATE +** TRIGGER statement is replaced with the second argument and the result +** returned. This is analagous to renameTableFunc() above, except for CREATE +** TRIGGER, not CREATE INDEX and CREATE TABLE. +*/ +static void renameTriggerFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + unsigned char const *zSql = sqlite3_value_text(argv[0]); + unsigned char const *zTableName = sqlite3_value_text(argv[1]); + + int token; + Token tname; + int dist = 3; + char const *zCsr = zSql; + int len = 0; + char *zRet; + + /* The principle used to locate the table name in the CREATE TRIGGER + ** statement is that the table name is the first token that is immediatedly + ** preceded by either TK_ON or TK_DOT and immediatedly followed by one + ** of TK_WHEN, TK_BEGIN or TK_FOR. + */ + if( zSql ){ + do { + /* Store the token that zCsr points to in tname. */ + tname.z = zCsr; + tname.n = len; + + /* Advance zCsr to the next token. Store that token type in 'token', + ** and it's length in 'len' (to be used next iteration of this loop). + */ + do { + zCsr += len; + len = sqlite3GetToken(zCsr, &token); + }while( token==TK_SPACE ); + assert( len>0 ); + + /* Variable 'dist' stores the number of tokens read since the most + ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN + ** token is read and 'dist' equals 2, the condition stated above + ** to be met. + ** + ** Note that ON cannot be a database, table or column name, so + ** there is no need to worry about syntax like + ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. + */ + dist++; + if( token==TK_DOT || token==TK_ON ){ + dist = 0; + } + } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); + + /* Variable tname now contains the token that is the old table-name + ** in the CREATE TRIGGER statement. + */ + zRet = sqlite3MPrintf("%.*s%Q%s", tname.z - zSql, zSql, + zTableName, tname.z+tname.n); + sqlite3_result_text(context, zRet, -1, sqlite3FreeX); + } +} +#endif /* !SQLITE_OMIT_TRIGGER */ + +/* +** Register built-in functions used to help implement ALTER TABLE +*/ +void sqlite3AlterFunctions(sqlite3 *db){ + static const struct { + char *zName; + signed char nArg; + void (*xFunc)(sqlite3_context*,int,sqlite3_value **); + } aFuncs[] = { + { "sqlite_rename_table", 2, renameTableFunc}, +#ifndef SQLITE_OMIT_TRIGGER + { "sqlite_rename_trigger", 2, renameTriggerFunc}, +#endif + }; + int i; + + for(i=0; iiDb!=1 ){ + for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){ + if( pTrig->iDb==1 ){ + if( !zWhere ){ + zWhere = sqlite3MPrintf("name=%Q", pTrig->name); + }else{ + tmp = zWhere; + zWhere = sqlite3MPrintf("%s OR name=%Q", zWhere, pTrig->name); + sqliteFree(tmp); + } + } + } + } + return zWhere; +} + +/* +** Generate code to drop and reload the internal representation of table +** pTab from the database, including triggers and temporary triggers. +** Argument zName is the name of the table in the database schema at +** the time the generated code is executed. This can be different from +** pTab->zName if this function is being called to code part of an +** "ALTER TABLE RENAME TO" statement. +*/ +static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ + Vdbe *v; + char *zWhere; + int iDb; +#ifndef SQLITE_OMIT_TRIGGER + Trigger *pTrig; +#endif + + v = sqlite3GetVdbe(pParse); + if( !v ) return; + iDb = pTab->iDb; + +#ifndef SQLITE_OMIT_TRIGGER + /* Drop any table triggers from the internal schema. */ + for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){ + assert( pTrig->iDb==iDb || pTrig->iDb==1 ); + sqlite3VdbeOp3(v, OP_DropTrigger, pTrig->iDb, 0, pTrig->name, 0); + } +#endif + + /* Drop the table and index from the internal schema */ + sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); + + /* Reload the table, index and permanent trigger schemas. */ + zWhere = sqlite3MPrintf("tbl_name=%Q", zName); + if( !zWhere ) return; + sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC); + +#ifndef SQLITE_OMIT_TRIGGER + /* Now, if the table is not stored in the temp database, reload any temp + ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. + */ + if( (zWhere=whereTempTriggers(pParse, pTab)) ){ + sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC); + } +#endif +} + +/* +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. +*/ +void sqlite3AlterRenameTable( + Parse *pParse, /* Parser context. */ + SrcList *pSrc, /* The table to rename. */ + Token *pName /* The new table name. */ +){ + int iDb; /* Database that contains the table */ + char *zDb; /* Name of database iDb */ + Table *pTab; /* Table being renamed */ + char *zName = 0; /* NULL-terminated version of pName */ + sqlite3 *db = pParse->db; /* Database connection */ + Vdbe *v; +#ifndef SQLITE_OMIT_TRIGGER + char *zWhere = 0; /* Where clause to locate temp triggers */ +#endif + + assert( pSrc->nSrc==1 ); + + pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); + if( !pTab ) goto exit_rename_table; + iDb = pTab->iDb; + zDb = db->aDb[iDb].zName; + + /* Get a NULL terminated version of the new table name. */ + zName = sqlite3NameFromToken(pName); + if( !zName ) goto exit_rename_table; + + /* Check that a table or index named 'zName' does not already exist + ** in database iDb. If so, this is an error. + */ + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + sqlite3ErrorMsg(pParse, + "there is already another table or index with this name: %s", zName); + goto exit_rename_table; + } + + /* Make sure it is not a system table being altered, or a reserved name + ** that the table is being renamed to. + */ + if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){ + sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); + goto exit_rename_table; + } + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ + goto exit_rename_table; + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + goto exit_rename_table; + } +#endif + + /* Begin a transaction and code the VerifyCookie for database iDb. + ** Then modify the schema cookie (since the ALTER TABLE modifies the + ** schema). + */ + v = sqlite3GetVdbe(pParse); + if( v==0 ){ + goto exit_rename_table; + } + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3ChangeCookie(db, v, iDb); + + /* Modify the sqlite_master table to use the new table name. */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " +#ifdef SQLITE_OMIT_TRIGGER + "sql = sqlite_rename_table(sql, %Q), " +#else + "sql = CASE " + "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" + "ELSE sqlite_rename_table(sql, %Q) END, " +#endif + "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name, %d+18,10) " + "ELSE name END " + "WHERE tbl_name=%Q AND " + "(type='table' OR type='index' OR type='trigger');", + zDb, SCHEMA_TABLE(iDb), zName, zName, zName, +#ifndef SQLITE_OMIT_TRIGGER + zName, +#endif + zName, strlen(pTab->zName), pTab->zName + ); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If the sqlite_sequence table exists in this database, then update + ** it with the new table name. + */ + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, + "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q", + zDb, zName, pTab->zName); + } +#endif + +#ifndef SQLITE_OMIT_TRIGGER + /* If there are TEMP triggers on this table, modify the sqlite_temp_master + ** table. Don't do this if the table being ALTERed is itself located in + ** the temp database. + */ + if( (zWhere=whereTempTriggers(pParse, pTab)) ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_temp_master SET " + "sql = sqlite_rename_trigger(sql, %Q), " + "tbl_name = %Q " + "WHERE %s;", zName, zName, zWhere); + sqliteFree(zWhere); + } +#endif + + /* Drop and reload the internal table schema. */ + reloadTableSchema(pParse, pTab, zName); + +exit_rename_table: + sqlite3SrcListDelete(pSrc); + sqliteFree(zName); +} + + +/* +** This function is called after an "ALTER TABLE ... ADD" statement +** has been parsed. Argument pColDef contains the text of the new +** column definition. +** +** The Table structure pParse->pNewTable was extended to include +** the new column during parsing. +*/ +void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ + Table *pNew; /* Copy of pParse->pNewTable */ + Table *pTab; /* Table being altered */ + int iDb; /* Database number */ + const char *zDb; /* Database name */ + const char *zTab; /* Table name */ + char *zCol; /* Null-terminated column definition */ + Column *pCol; /* The new column */ + Expr *pDflt; /* Default value for the new column */ + Vdbe *v; + + if( pParse->nErr ) return; + pNew = pParse->pNewTable; + assert( pNew ); + + iDb = pNew->iDb; + zDb = pParse->db->aDb[iDb].zName; + zTab = pNew->zName; + pCol = &pNew->aCol[pNew->nCol-1]; + pDflt = pCol->pDflt; + pTab = sqlite3FindTable(pParse->db, zTab, zDb); + assert( pTab ); + + /* If the default value for the new column was specified with a + ** literal NULL, then set pDflt to 0. This simplifies checking + ** for an SQL NULL default below. + */ + if( pDflt && pDflt->op==TK_NULL ){ + pDflt = 0; + } + + /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. + ** If there is a NOT NULL constraint, then the default value for the + ** column must not be NULL. + */ + if( pCol->isPrimKey ){ + sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); + return; + } + if( pNew->pIndex ){ + sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); + return; + } + if( pCol->notNull && !pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a NOT NULL column with default value NULL"); + return; + } + + /* Ensure the default expression is something that sqlite3ValueFromExpr() + ** can handle (i.e. not CURRENT_TIME etc.) + */ + if( pDflt ){ + sqlite3_value *pVal; + if( sqlite3ValueFromExpr(pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ + /* malloc() has failed */ + return; + } + if( !pVal ){ + sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); + return; + } + sqlite3ValueFree(pVal); + } + + /* Modify the CREATE TABLE statement. */ + zCol = sqliteStrNDup(pColDef->z, pColDef->n); + if( zCol ){ + char *zEnd = &zCol[pColDef->n-1]; + while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){ + *zEnd-- = '\0'; + } + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET " + "sql = substr(sql,0,%d) || ', ' || %Q || substr(sql,%d,length(sql)) " + "WHERE type = 'table' AND name = %Q", + zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1, + zTab + ); + sqliteFree(zCol); + } + + /* If the default value of the new column is NULL, then set the file + ** format to 2. If the default value of the new column is not NULL, + ** the file format becomes 3. + */ + if( (v=sqlite3GetVdbe(pParse)) ){ + int f = (pDflt?3:2); + + /* Only set the file format to $f if it is currently less than $f. */ + sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); + sqlite3VdbeAddOp(v, OP_Integer, f, 0); + sqlite3VdbeAddOp(v, OP_Ge, 0, sqlite3VdbeCurrentAddr(v)+3); + sqlite3VdbeAddOp(v, OP_Integer, f, 0); + sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); + } + + /* Reload the schema of the modified table. */ + reloadTableSchema(pParse, pTab, pTab->zName); +} + + +/* +** This function is called by the parser after the table-name in +** an "ALTER TABLE ADD" statement is parsed. Argument +** pSrc is the full-name of the table being altered. +** +** This routine makes a (partial) copy of the Table structure +** for the table being altered and sets Parse.pNewTable to point +** to it. Routines called by the parser as the column definition +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to +** the copy. The copy of the Table structure is deleted by tokenize.c +** after parsing is finished. +** +** Routine sqlite3AlterFinishAddColumn() will be called to complete +** coding the "ALTER TABLE ... ADD" statement. +*/ +void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ + Table *pNew; + Table *pTab; + Vdbe *v; + int iDb; + int i; + int nAlloc; + + /* Look up the table being altered. */ + assert( !pParse->pNewTable ); + pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase); + if( !pTab ) goto exit_begin_add_column; + + /* Make sure this is not an attempt to ALTER a view. */ + if( pTab->pSelect ){ + sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); + goto exit_begin_add_column; + } + + assert( pTab->addColOffset>0 ); + iDb = pTab->iDb; + + /* Put a copy of the Table struct in Parse.pNewTable for the + ** sqlite3AddColumn() function and friends to modify. + */ + pNew = (Table *)sqliteMalloc(sizeof(Table)); + if( !pNew ) goto exit_begin_add_column; + pParse->pNewTable = pNew; + pNew->nCol = pTab->nCol; + nAlloc = ((pNew->nCol)/8)+8; + pNew->aCol = (Column *)sqliteMalloc(sizeof(Column)*nAlloc); + pNew->zName = sqliteStrDup(pTab->zName); + if( !pNew->aCol || !pNew->zName ){ + goto exit_begin_add_column; + } + memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); + for(i=0; inCol; i++){ + Column *pCol = &pNew->aCol[i]; + pCol->zName = sqliteStrDup(pCol->zName); + pCol->zType = 0; + pCol->pDflt = 0; + } + pNew->iDb = iDb; + pNew->addColOffset = pTab->addColOffset; + + /* Begin a transaction and increment the schema cookie. */ + sqlite3BeginWriteOperation(pParse, 0, iDb); + v = sqlite3GetVdbe(pParse); + if( !v ) goto exit_begin_add_column; + sqlite3ChangeCookie(pParse->db, v, iDb); + +exit_begin_add_column: + sqlite3SrcListDelete(pSrc); + return; +} +#endif /* SQLITE_ALTER_TABLE */ diff --git a/db/sqlite3/src/attach.c b/db/sqlite3/src/attach.c index d20c662b999..92366508ebc 100644 --- a/db/sqlite3/src/attach.c +++ b/db/sqlite3/src/attach.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.28 2004/09/06 17:24:12 drh Exp $ +** $Id: attach.c,v 1.33 2005/03/16 12:15:21 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -32,12 +32,14 @@ void sqlite3Attach( ){ Db *aNew; int rc, i; - char *zFile, *zName; + char *zFile = 0; + char *zName = 0; sqlite3 *db; Vdbe *v; v = sqlite3GetVdbe(pParse); if( !v ) return; + sqlite3VdbeAddOp(v, OP_Expire, 1, 0); sqlite3VdbeAddOp(v, OP_Halt, 0, 0); if( pParse->explain ) return; db = pParse->db; @@ -54,34 +56,40 @@ void sqlite3Attach( return; } - zFile = sqlite3NameFromToken(pFilename);; - if( zFile==0 ) return; + zFile = sqlite3NameFromToken(pFilename); + if( zFile==0 ){ + goto attach_end; + } #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){ - sqliteFree(zFile); - return; + goto attach_end; } #endif /* SQLITE_OMIT_AUTHORIZATION */ zName = sqlite3NameFromToken(pDbname); - if( zName==0 ) return; + if( zName==0 ){ + goto attach_end; + } for(i=0; inDb; i++){ char *z = db->aDb[i].zName; if( z && sqlite3StrICmp(z, zName)==0 ){ - sqlite3ErrorMsg(pParse, "database %z is already in use", zName); + sqlite3ErrorMsg(pParse, "database %s is already in use", zName); pParse->rc = SQLITE_ERROR; - sqliteFree(zFile); - return; + goto attach_end; } } if( db->aDb==db->aDbStatic ){ aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); - if( aNew==0 ) return; + if( aNew==0 ){ + goto attach_end; + } memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); - if( aNew==0 ) return; + if( aNew==0 ){ + goto attach_end; + } } db->aDb = aNew; aNew = &db->aDb[db->nDb++]; @@ -91,6 +99,7 @@ void sqlite3Attach( sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1); aNew->zName = zName; + zName = 0; aNew->safety_level = 3; rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); if( rc ){ @@ -125,7 +134,6 @@ void sqlite3Attach( } } #endif - sqliteFree(zFile); db->flags &= ~SQLITE_Initialized; if( pParse->nErr==0 && rc==SQLITE_OK ){ rc = sqlite3ReadSchema(pParse); @@ -143,6 +151,10 @@ void sqlite3Attach( pParse->rc = SQLITE_ERROR; } } + +attach_end: + sqliteFree(zFile); + sqliteFree(zName); } /* @@ -157,26 +169,30 @@ void sqlite3Detach(Parse *pParse, Token *pDbname){ sqlite3 *db; Vdbe *v; Db *pDb = 0; + char *zName; v = sqlite3GetVdbe(pParse); if( !v ) return; + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); sqlite3VdbeAddOp(v, OP_Halt, 0, 0); if( pParse->explain ) return; db = pParse->db; + zName = sqlite3NameFromToken(pDbname); + if( zName==0 ) return; for(i=0; inDb; i++){ pDb = &db->aDb[i]; - if( pDb->pBt==0 || pDb->zName==0 ) continue; - if( strlen(pDb->zName)!=pDbname->n ) continue; - if( sqlite3StrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break; + if( pDb->pBt==0 ) continue; + if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; } if( i>=db->nDb ){ - sqlite3ErrorMsg(pParse, "no such database: %T", pDbname); + sqlite3ErrorMsg(pParse, "no such database: %z", zName); return; } if( i<2 ){ - sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname); + sqlite3ErrorMsg(pParse, "cannot detach database %z", zName); return; } + sqliteFree(zName); if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction"); pParse->rc = SQLITE_ERROR; @@ -251,11 +267,14 @@ int sqlite3FixSrcList( pFix->zType, pFix->pName, pItem->zDatabase); return 1; } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; +#endif } return 0; } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) int sqlite3FixSelect( DbFixer *pFix, /* Context of the fixation */ Select *pSelect /* The SELECT statement to be fixed to one database */ @@ -309,6 +328,9 @@ int sqlite3FixExprList( } return 0; } +#endif + +#ifndef SQLITE_OMIT_TRIGGER int sqlite3FixTriggerStep( DbFixer *pFix, /* Context of the fixation */ TriggerStep *pStep /* The trigger step be fixed to one database */ @@ -327,3 +349,4 @@ int sqlite3FixTriggerStep( } return 0; } +#endif diff --git a/db/sqlite3/src/auth.c b/db/sqlite3/src/auth.c index 17f1df9bb6a..aa387cc603a 100644 --- a/db/sqlite3/src/auth.c +++ b/db/sqlite3/src/auth.c @@ -14,7 +14,7 @@ ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: auth.c,v 1.19 2004/09/30 13:43:13 drh Exp $ +** $Id: auth.c,v 1.21 2005/01/29 08:32:44 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -76,6 +76,7 @@ int sqlite3_set_authorizer( ){ db->xAuth = xAuth; db->pAuthArg = pArg; + sqlite3ExpirePreparedStatements(db); return SQLITE_OK; } @@ -114,10 +115,10 @@ void sqlite3AuthRead( if( db->xAuth==0 ) return; assert( pExpr->op==TK_COLUMN ); - for(iSrc=0; iSrcnSrc; iSrc++){ + for(iSrc=0; pTabList && iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; } - if( iSrc>=0 && iSrcnSrc ){ + if( iSrc>=0 && pTabList && iSrcnSrc ){ pTab = pTabList->a[iSrc].pTab; }else if( (pStack = pParse->trigStack)!=0 ){ /* This must be an attempt to read the NEW or OLD pseudo-tables diff --git a/db/sqlite3/src/btree.c b/db/sqlite3/src/btree.c index a5bd8861399..b2c34e533fa 100644 --- a/db/sqlite3/src/btree.c +++ b/db/sqlite3/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.192 2004/10/05 02:41:42 drh Exp $ +** $Id: btree.c,v 1.253 2005/03/21 04:04:02 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -211,6 +211,11 @@ #include "os.h" #include +/* +** This macro rounds values up so that if the value is an address it +** is guaranteed to be an address that is aligned to an 8-byte boundary. +*/ +#define FORCE_ALIGNMENT(X) (((X)+7)&~7) /* The following value is the maximum cell size assuming a maximum page ** size give above. @@ -299,12 +304,17 @@ struct Btree { u8 minEmbedFrac; /* Minimum payload as % of total page size */ u8 minLeafFrac; /* Minimum leaf payload as % of total page size */ u8 pageSizeFixed; /* True if the page size can no longer be changed */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 autoVacuum; /* True if database supports auto-vacuum */ +#endif u16 pageSize; /* Total number of bytes on a page */ + u16 psAligned; /* pageSize rounded up to a multiple of 8 */ u16 usableSize; /* Number of usable bytes on each page */ int maxLocal; /* Maximum local payload in non-LEAFDATA tables */ int minLocal; /* Minimum local payload in non-LEAFDATA tables */ int maxLeaf; /* Maximum local payload in a LEAFDATA table */ int minLeaf; /* Minimum local payload in a LEAFDATA table */ + BusyHandler *pBusyHandler; /* Callback for when there is lock contention */ }; typedef Btree Bt; @@ -347,15 +357,26 @@ struct BtCursor { CellInfo info; /* A parse of the cell we are pointing at */ u8 wrFlag; /* True if writable */ u8 isValid; /* TRUE if points to a valid entry */ - u8 status; /* Set to SQLITE_ABORT if cursors is invalidated */ }; +/* +** The TRACE macro will print high-level status information about the +** btree operation when the global variable sqlite3_btree_trace is +** enabled. +*/ +#if SQLITE_TEST +# define TRACE(X) if( sqlite3_btree_trace )\ + { sqlite3DebugPrintf X; fflush(stdout); } +#else +# define TRACE(X) +#endif +int sqlite3_btree_trace=0; /* True to enable tracing */ + /* ** Forward declaration */ static int checkReadLocks(Btree*,Pgno,BtCursor*); - /* ** Read or write a two- and four-byte big-endian integer values. */ @@ -385,6 +406,136 @@ static void put4byte(unsigned char *p, u32 v){ #define getVarint32 sqlite3GetVarint32 #define putVarint sqlite3PutVarint +/* The database page the PENDING_BYTE occupies. This page is never used. +** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They +** should possibly be consolidated (presumably in pager.h). +*/ +#define PENDING_BYTE_PAGE(pBt) ((PENDING_BYTE/(pBt)->pageSize)+1) + +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** These macros define the location of the pointer-map entry for a +** database page. The first argument to each is the number of usable +** bytes on each page of the database (often 1024). The second is the +** page number to look up in the pointer map. +** +** PTRMAP_PAGENO returns the database page number of the pointer-map +** page that stores the required pointer. PTRMAP_PTROFFSET returns +** the offset of the requested map entry. +** +** If the pgno argument passed to PTRMAP_PAGENO is a pointer-map page, +** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be +** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements +** this test. +*/ +#define PTRMAP_PAGENO(pgsz, pgno) (((pgno-2)/(pgsz/5+1))*(pgsz/5+1)+2) +#define PTRMAP_PTROFFSET(pgsz, pgno) (((pgno-2)%(pgsz/5+1)-1)*5) +#define PTRMAP_ISPAGE(pgsz, pgno) (PTRMAP_PAGENO(pgsz,pgno)==pgno) + +/* +** The pointer map is a lookup table that identifies the parent page for +** each child page in the database file. The parent page is the page that +** contains a pointer to the child. Every page in the database contains +** 0 or 1 parent pages. (In this context 'database page' refers +** to any page that is not part of the pointer map itself.) Each pointer map +** entry consists of a single byte 'type' and a 4 byte parent page number. +** The PTRMAP_XXX identifiers below are the valid types. +** +** The purpose of the pointer map is to facility moving pages from one +** position in the file to another as part of autovacuum. When a page +** is moved, the pointer in its parent must be updated to point to the +** new location. The pointer map is used to locate the parent page quickly. +** +** PTRMAP_ROOTPAGE: The database page is a root-page. The page-number is not +** used in this case. +** +** PTRMAP_FREEPAGE: The database page is an unused (free) page. The page-number +** is not used in this case. +** +** PTRMAP_OVERFLOW1: The database page is the first page in a list of +** overflow pages. The page number identifies the page that +** contains the cell with a pointer to this overflow page. +** +** PTRMAP_OVERFLOW2: The database page is the second or later page in a list of +** overflow pages. The page-number identifies the previous +** page in the overflow page list. +** +** PTRMAP_BTREE: The database page is a non-root btree page. The page number +** identifies the parent page in the btree. +*/ +#define PTRMAP_ROOTPAGE 1 +#define PTRMAP_FREEPAGE 2 +#define PTRMAP_OVERFLOW1 3 +#define PTRMAP_OVERFLOW2 4 +#define PTRMAP_BTREE 5 + +/* +** Write an entry into the pointer map. +** +** This routine updates the pointer map entry for page number 'key' +** so that it maps to type 'eType' and parent page number 'pgno'. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapPut(Btree *pBt, Pgno key, u8 eType, Pgno parent){ + u8 *pPtrmap; /* The pointer map page */ + Pgno iPtrmap; /* The pointer map page number */ + int offset; /* Offset in pointer map page */ + int rc; + + assert( pBt->autoVacuum ); + if( key==0 ){ + return SQLITE_CORRUPT; + } + iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key); + rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); + if( rc!=SQLITE_OK ){ + return rc; + } + offset = PTRMAP_PTROFFSET(pBt->usableSize, key); + + if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ + TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); + rc = sqlite3pager_write(pPtrmap); + if( rc==SQLITE_OK ){ + pPtrmap[offset] = eType; + put4byte(&pPtrmap[offset+1], parent); + } + } + + sqlite3pager_unref(pPtrmap); + return rc; +} + +/* +** Read an entry from the pointer map. +** +** This routine retrieves the pointer map entry for page 'key', writing +** the type and parent page number to *pEType and *pPgno respectively. +** An error code is returned if something goes wrong, otherwise SQLITE_OK. +*/ +static int ptrmapGet(Btree *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ + int iPtrmap; /* Pointer map page index */ + u8 *pPtrmap; /* Pointer map page data */ + int offset; /* Offset of entry in pointer map */ + int rc; + + iPtrmap = PTRMAP_PAGENO(pBt->usableSize, key); + rc = sqlite3pager_get(pBt->pPager, iPtrmap, (void **)&pPtrmap); + if( rc!=0 ){ + return rc; + } + + offset = PTRMAP_PTROFFSET(pBt->usableSize, key); + if( pEType ) *pEType = pPtrmap[offset]; + if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); + + sqlite3pager_unref(pPtrmap); + if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT; + return SQLITE_OK; +} + +#endif /* SQLITE_OMIT_AUTOVACUUM */ + /* ** Given a btree page and a cell index (0 means the first cell on ** the page, 1 means the second cell, and so forth) return a pointer @@ -514,6 +665,36 @@ static int cellSizePtr(MemPage *pPage, u8 *pCell){ return info.nSize; } +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** If the cell pCell, part of page pPage contains a pointer +** to an overflow page, insert an entry into the pointer-map +** for the overflow page. +*/ +static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ + if( pCell ){ + CellInfo info; + parseCellPtr(pPage, pCell, &info); + if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ + Pgno ovfl = get4byte(&pCell[info.iOverflow]); + return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno); + } + } + return SQLITE_OK; +} +/* +** If the cell with index iCell on page pPage contains a pointer +** to an overflow page, insert an entry into the pointer-map +** for the overflow page. +*/ +static int ptrmapPutOvfl(MemPage *pPage, int iCell){ + u8 *pCell; + pCell = findOverflowCell(pPage, iCell); + return ptrmapPutOvflPtr(pPage, pCell); +} +#endif + + /* ** Do sanity checking on a page. Throw an exception if anything is ** not right. @@ -533,7 +714,7 @@ static void _pageIntegrity(MemPage *pPage){ used = sqliteMallocRaw( pPage->pBt->pageSize ); if( used==0 ) return; usableSize = pPage->pBt->usableSize; - assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] ); + assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->psAligned] ); hdr = pPage->hdrOffset; assert( hdr==(pPage->pgno==1 ? 100 : 0) ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); @@ -824,7 +1005,6 @@ static int initPage( MemPage *pParent /* The parent. Might be NULL */ ){ int pc; /* Address of a freeblock within pPage->aData[] */ - int i; /* Loop counter */ int hdr; /* Offset to beginning of page header */ u8 *data; /* Equal to pPage->aData */ Btree *pBt; /* The main btree structure */ @@ -837,7 +1017,7 @@ static int initPage( assert( pBt!=0 ); assert( pParent==0 || pParent->pBt==pBt ); assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) ); - assert( pPage->aData == &((unsigned char*)pPage)[-pBt->pageSize] ); + assert( pPage->aData == &((unsigned char*)pPage)[-pBt->psAligned] ); if( pPage->pParent!=pParent && (pPage->pParent!=0 || pPage->isInit) ){ /* The parent page should never change unless the file is corrupt */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */ @@ -868,17 +1048,12 @@ static int initPage( /* Compute the total free space on the page */ pc = get2byte(&data[hdr+1]); nFree = data[hdr+7] + top - (cellOffset + 2*pPage->nCell); - i = 0; while( pc>0 ){ int next, size; if( pc>usableSize-4 ){ /* Free block is off the page */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */ } - if( i++>SQLITE_MAX_PAGE_SIZE/4 ){ - /* The free block list forms an infinite loop */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ - } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); if( next>0 && next<=pc+size+3 ){ @@ -910,7 +1085,7 @@ static void zeroPage(MemPage *pPage, int flags){ int first; assert( sqlite3pager_pagenumber(data)==pPage->pgno ); - assert( &data[pBt->pageSize] == (unsigned char*)pPage ); + assert( &data[pBt->psAligned] == (unsigned char*)pPage ); assert( sqlite3pager_iswriteable(data) ); memset(&data[hdr], 0, pBt->usableSize - hdr); data[hdr] = flags; @@ -939,7 +1114,7 @@ static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){ MemPage *pPage; rc = sqlite3pager_get(pBt->pPager, pgno, (void**)&aData); if( rc ) return rc; - pPage = (MemPage*)&aData[pBt->pageSize]; + pPage = (MemPage*)&aData[pBt->psAligned]; pPage->aData = aData; pPage->pBt = pBt; pPage->pgno = pgno; @@ -978,7 +1153,7 @@ static void releasePage(MemPage *pPage){ if( pPage ){ assert( pPage->aData ); assert( pPage->pBt ); - assert( &pPage->aData[pPage->pBt->pageSize]==(unsigned char*)pPage ); + assert( &pPage->aData[pPage->pBt->psAligned]==(unsigned char*)pPage ); sqlite3pager_unref(pPage->aData); } } @@ -989,7 +1164,7 @@ static void releasePage(MemPage *pPage){ ** happens. */ static void pageDestructor(void *pData, int pageSize){ - MemPage *pPage = (MemPage*)&((char*)pData)[pageSize]; + MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)]; if( pPage->pParent ){ MemPage *pParent = pPage->pParent; pPage->pParent = 0; @@ -1007,7 +1182,7 @@ static void pageDestructor(void *pData, int pageSize){ ** page to agree with the restored data. */ static void pageReinit(void *pData, int pageSize){ - MemPage *pPage = (MemPage*)&((char*)pData)[pageSize]; + MemPage *pPage = (MemPage*)&((char*)pData)[FORCE_ALIGNMENT(pageSize)]; if( pPage->isInit ){ pPage->isInit = 0; initPage(pPage, pPage->pParent); @@ -1049,8 +1224,7 @@ int sqlite3BtreeOpen( *ppBtree = 0; return SQLITE_NOMEM; } - rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, - (flags & BTREE_OMIT_JOURNAL)==0); + rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags); if( rc!=SQLITE_OK ){ if( pBt->pPager ) sqlite3pager_close(pBt->pPager); sqliteFree(pBt); @@ -1069,6 +1243,21 @@ int sqlite3BtreeOpen( pBt->maxEmbedFrac = 64; /* 25% */ pBt->minEmbedFrac = 32; /* 12.5% */ pBt->minLeafFrac = 32; /* 12.5% */ +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the magic name ":memory:" will create an in-memory database, then + ** do not set the auto-vacuum flag, even if SQLITE_DEFAULT_AUTOVACUUM + ** is true. On the other hand, if SQLITE_OMIT_MEMORYDB has been defined, + ** then ":memory:" is just a regular file-name. Respect the auto-vacuum + ** default in this case. + */ +#ifndef SQLITE_OMIT_MEMORYDB + if( zFilename && strcmp(zFilename,":memory:") ){ +#else + if( zFilename ){ +#endif + pBt->autoVacuum = SQLITE_DEFAULT_AUTOVACUUM; + } +#endif nReserve = 0; }else{ nReserve = zDbHeader[20]; @@ -1076,8 +1265,12 @@ int sqlite3BtreeOpen( pBt->minEmbedFrac = zDbHeader[22]; pBt->minLeafFrac = zDbHeader[23]; pBt->pageSizeFixed = 1; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0); +#endif } pBt->usableSize = pBt->pageSize - nReserve; + pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); sqlite3pager_set_pagesize(pBt->pPager, pBt->pageSize); *ppBtree = pBt; return SQLITE_OK; @@ -1099,6 +1292,7 @@ int sqlite3BtreeClose(Btree *pBt){ ** Change the busy handler callback function. */ int sqlite3BtreeSetBusyHandler(Btree *pBt, BusyHandler *pHandler){ + pBt->pBusyHandler = pHandler; sqlite3pager_set_busyhandler(pBt->pPager, pHandler); return SQLITE_OK; } @@ -1131,13 +1325,28 @@ int sqlite3BtreeSetCacheSize(Btree *pBt, int mxPage){ ** is a very low but non-zero probability of damage. Level 3 reduces the ** probability of damage to near zero but with a write performance reduction. */ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS int sqlite3BtreeSetSafetyLevel(Btree *pBt, int level){ sqlite3pager_set_safety_level(pBt->pPager, level); return SQLITE_OK; } +#endif +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Change the default pages size and the number of reserved bytes per page. +** +** The page size must be a power of 2 between 512 and 65536. If the page +** size supplied does not meet this constraint then the page size is not +** changed. +** +** Page sizes are constrained to be a power of two so that the region +** of the database file used for locking (beginning at PENDING_BYTE, +** the first byte past the 1GB boundary, 0x40000000) needs to occur +** at the beginning of a page. +** +** If parameter nReserve is less than zero, then the number of reserved +** bytes per page is left unchanged. */ int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){ if( pBt->pageSizeFixed ){ @@ -1146,8 +1355,10 @@ int sqlite3BtreeSetPageSize(Btree *pBt, int pageSize, int nReserve){ if( nReserve<0 ){ nReserve = pBt->pageSize - pBt->usableSize; } - if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ){ + if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE && + ((pageSize-1)&pageSize)==0 ){ pBt->pageSize = pageSize; + pBt->psAligned = FORCE_ALIGNMENT(pageSize); sqlite3pager_set_pagesize(pBt->pPager, pageSize); } pBt->usableSize = pBt->pageSize - nReserve; @@ -1163,6 +1374,38 @@ int sqlite3BtreeGetPageSize(Btree *pBt){ int sqlite3BtreeGetReserve(Btree *pBt){ return pBt->pageSize - pBt->usableSize; } +#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */ + +/* +** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' +** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it +** is disabled. The default value for the auto-vacuum property is +** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. +*/ +int sqlite3BtreeSetAutoVacuum(Btree *pBt, int autoVacuum){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return SQLITE_READONLY; +#else + if( pBt->pageSizeFixed ){ + return SQLITE_READONLY; + } + pBt->autoVacuum = (autoVacuum?1:0); + return SQLITE_OK; +#endif +} + +/* +** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** enabled 1 is returned. Otherwise 0. +*/ +int sqlite3BtreeGetAutoVacuum(Btree *pBt){ +#ifdef SQLITE_OMIT_AUTOVACUUM + return 0; +#else + return pBt->autoVacuum; +#endif +} + /* ** Get a reference to pPage1 of the database file. This will @@ -1199,9 +1442,13 @@ static int lockBtree(Btree *pBt){ if( pBt->usableSize<500 ){ goto page1_init_failed; } + pBt->psAligned = FORCE_ALIGNMENT(pBt->pageSize); pBt->maxEmbedFrac = page1[21]; pBt->minEmbedFrac = page1[22]; pBt->minLeafFrac = page1[23]; +#ifndef SQLITE_OMIT_AUTOVACUUM + pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); +#endif } /* maxLocal is the maximum amount of payload to store locally for @@ -1234,6 +1481,20 @@ page1_init_failed: return rc; } +/* +** This routine works like lockBtree() except that it also invokes the +** busy callback if there is lock contention. +*/ +static int lockBtreeWithRetry(Btree *pBt){ + int rc = SQLITE_OK; + if( pBt->inTrans==TRANS_NONE ){ + rc = sqlite3BtreeBeginTrans(pBt, 0); + pBt->inTrans = TRANS_NONE; + } + return rc; +} + + /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then @@ -1248,7 +1509,7 @@ static void unlockBtreeIfUnused(Btree *pBt){ if( pBt->inTrans==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ if( pBt->pPage1->aData==0 ){ MemPage *pPage = pBt->pPage1; - pPage->aData = &((char*)pPage)[-pBt->pageSize]; + pPage->aData = &((char*)pPage)[-pBt->psAligned]; pPage->pBt = pBt; pPage->pgno = 1; } @@ -1284,6 +1545,11 @@ static int newDatabase(Btree *pBt){ memset(&data[24], 0, 100-24); zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA ); pBt->pageSizeFixed = 1; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + put4byte(&data[36 + 4*4], 1); + } +#endif return SQLITE_OK; } @@ -1293,7 +1559,7 @@ static int newDatabase(Btree *pBt){ ** transaction. If the second argument is 2 or more and exclusive ** transaction is started, meaning that no other process is allowed ** to access the database. A preexisting transaction may not be -** upgrade to exclusive by calling this routine a second time - the +** upgraded to exclusive by calling this routine a second time - the ** exclusivity flag only works for a new transaction. ** ** A write-transaction must be started before attempting any @@ -1308,46 +1574,364 @@ static int newDatabase(Btree *pBt){ ** sqlite3BtreeDelete() ** sqlite3BtreeUpdateMeta() ** -** If wrflag is true, then nMaster specifies the maximum length of -** a master journal file name supplied later via sqlite3BtreeSync(). -** This is so that appropriate space can be allocated in the journal file -** when it is created.. +** If an initial attempt to acquire the lock fails because of lock contention +** and the database was previously unlocked, then invoke the busy handler +** if there is one. But if there was previously a read-lock, do not +** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is +** returned when there is already a read-lock in order to avoid a deadlock. +** +** Suppose there are two processes A and B. A has a read lock and B has +** a reserved lock. B tries to promote to exclusive but is blocked because +** of A's read lock. A tries to promote to reserved but is blocked by B. +** One or the other of the two processes must give way or there can be +** no progress. By returning SQLITE_BUSY and not invoking the busy callback +** when A already has a read lock, we encourage A to give up and let B +** proceed. */ int sqlite3BtreeBeginTrans(Btree *pBt, int wrflag){ int rc = SQLITE_OK; + int busy = 0; + BusyHandler *pH; /* If the btree is already in a write-transaction, or it ** is already in a read-transaction and a read-transaction ** is requested, this is a no-op. */ - if( pBt->inTrans==TRANS_WRITE || - (pBt->inTrans==TRANS_READ && !wrflag) ){ + if( pBt->inTrans==TRANS_WRITE || (pBt->inTrans==TRANS_READ && !wrflag) ){ return SQLITE_OK; } + + /* Write transactions are not possible on a read-only database */ if( pBt->readOnly && wrflag ){ return SQLITE_READONLY; } - if( pBt->pPage1==0 ){ - rc = lockBtree(pBt); - } - - if( rc==SQLITE_OK && wrflag ){ - rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1); + do { + if( pBt->pPage1==0 ){ + rc = lockBtree(pBt); + } + + if( rc==SQLITE_OK && wrflag ){ + rc = sqlite3pager_begin(pBt->pPage1->aData, wrflag>1); + if( rc==SQLITE_OK ){ + rc = newDatabase(pBt); + } + } + if( rc==SQLITE_OK ){ - rc = newDatabase(pBt); + pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); + if( wrflag ) pBt->inStmt = 0; + }else{ + unlockBtreeIfUnused(pBt); + } + }while( rc==SQLITE_BUSY && pBt->inTrans==TRANS_NONE && + (pH = pBt->pBusyHandler)!=0 && + pH->xFunc && pH->xFunc(pH->pArg, busy++) + ); + return rc; +} + +#ifndef SQLITE_OMIT_AUTOVACUUM + +/* +** Set the pointer-map entries for all children of page pPage. Also, if +** pPage contains cells that point to overflow pages, set the pointer +** map entries for the overflow pages as well. +*/ +static int setChildPtrmaps(MemPage *pPage){ + int i; /* Counter variable */ + int nCell; /* Number of cells in page pPage */ + int rc = SQLITE_OK; /* Return code */ + Btree *pBt = pPage->pBt; + int isInitOrig = pPage->isInit; + Pgno pgno = pPage->pgno; + + initPage(pPage, 0); + nCell = pPage->nCell; + + for(i=0; ileaf ){ + Pgno childPgno = get4byte(pCell); + rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); + if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out; } } - if( rc==SQLITE_OK ){ - pBt->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); - if( wrflag ) pBt->inStmt = 0; + if( !pPage->leaf ){ + Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); + rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); + } + +set_child_ptrmaps_out: + pPage->isInit = isInitOrig; + return rc; +} + +/* +** Somewhere on pPage, which is guarenteed to be a btree page, not an overflow +** page, is a pointer to page iFrom. Modify this pointer so that it points to +** iTo. Parameter eType describes the type of pointer to be modified, as +** follows: +** +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** page of pPage. +** +** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow +** page pointed to by one of the cells on pPage. +** +** PTRMAP_OVERFLOW2: pPage is an overflow-page. The pointer points at the next +** overflow page in the list. +*/ +static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ + if( eType==PTRMAP_OVERFLOW2 ){ + /* The pointer is always the first 4 bytes of the page in this case. */ + if( get4byte(pPage->aData)!=iFrom ){ + return SQLITE_CORRUPT; + } + put4byte(pPage->aData, iTo); }else{ - unlockBtreeIfUnused(pBt); + int isInitOrig = pPage->isInit; + int i; + int nCell; + + initPage(pPage, 0); + nCell = pPage->nCell; + + for(i=0; iaData[pPage->hdrOffset+8])!=iFrom ){ + return SQLITE_CORRUPT; + } + put4byte(&pPage->aData[pPage->hdrOffset+8], iTo); + } + + pPage->isInit = isInitOrig; + } + return SQLITE_OK; +} + + +/* +** Move the open database page pDbPage to location iFreePage in the +** database. The pDbPage reference remains valid. +*/ +static int relocatePage( + Btree *pBt, /* Btree */ + MemPage *pDbPage, /* Open page to move */ + u8 eType, /* Pointer map 'type' entry for pDbPage */ + Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ + Pgno iFreePage /* The location to move pDbPage to */ +){ + MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ + Pgno iDbPage = pDbPage->pgno; + Pager *pPager = pBt->pPager; + int rc; + + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); + + /* Move page iDbPage from it's current location to page number iFreePage */ + TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", + iDbPage, iFreePage, iPtrPage, eType)); + rc = sqlite3pager_movepage(pPager, pDbPage->aData, iFreePage); + if( rc!=SQLITE_OK ){ + return rc; + } + pDbPage->pgno = iFreePage; + + /* If pDbPage was a btree-page, then it may have child pages and/or cells + ** that point to overflow pages. The pointer map entries for all these + ** pages need to be changed. + ** + ** If pDbPage is an overflow page, then the first 4 bytes may store a + ** pointer to a subsequent overflow page. If this is the case, then + ** the pointer map needs to be updated for the subsequent overflow page. + */ + if( eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ){ + rc = setChildPtrmaps(pDbPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + Pgno nextOvfl = get4byte(pDbPage->aData); + if( nextOvfl!=0 ){ + rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } + + /* Fix the database pointer on page iPtrPage that pointed at iDbPage so + ** that it points at iFreePage. Also fix the pointer map entry for + ** iPtrPage. + */ + if( eType!=PTRMAP_ROOTPAGE ){ + rc = getPage(pBt, iPtrPage, &pPtrPage); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3pager_write(pPtrPage->aData); + if( rc!=SQLITE_OK ){ + releasePage(pPtrPage); + return rc; + } + rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); + releasePage(pPtrPage); + if( rc==SQLITE_OK ){ + rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage); + } } return rc; } +/* Forward declaration required by autoVacuumCommit(). */ +static int allocatePage(Btree *, MemPage **, Pgno *, Pgno, u8); + +/* +** This routine is called prior to sqlite3pager_commit when a transaction +** is commited for an auto-vacuum database. +*/ +static int autoVacuumCommit(Btree *pBt, Pgno *nTrunc){ + Pager *pPager = pBt->pPager; + Pgno nFreeList; /* Number of pages remaining on the free-list. */ + int nPtrMap; /* Number of pointer-map pages deallocated */ + Pgno origSize; /* Pages in the database file */ + Pgno finSize; /* Pages in the database file after truncation */ + int rc; /* Return code */ + u8 eType; + int pgsz = pBt->pageSize; /* Page size for this database */ + Pgno iDbPage; /* The database page to move */ + MemPage *pDbMemPage = 0; /* "" */ + Pgno iPtrPage; /* The page that contains a pointer to iDbPage */ + Pgno iFreePage; /* The free-list page to move iDbPage to */ + MemPage *pFreeMemPage = 0; /* "" */ + +#ifndef NDEBUG + int nRef = *sqlite3pager_stats(pPager); +#endif + + assert( pBt->autoVacuum ); + if( PTRMAP_ISPAGE(pgsz, sqlite3pager_pagecount(pPager)) ){ + return SQLITE_CORRUPT; + } + + /* Figure out how many free-pages are in the database. If there are no + ** free pages, then auto-vacuum is a no-op. + */ + nFreeList = get4byte(&pBt->pPage1->aData[36]); + if( nFreeList==0 ){ + *nTrunc = 0; + return SQLITE_OK; + } + + origSize = sqlite3pager_pagecount(pPager); + nPtrMap = (nFreeList-origSize+PTRMAP_PAGENO(pgsz, origSize)+pgsz/5)/(pgsz/5); + finSize = origSize - nFreeList - nPtrMap; + if( origSize>PENDING_BYTE_PAGE(pBt) && finSize<=PENDING_BYTE_PAGE(pBt) ){ + finSize--; + if( PTRMAP_ISPAGE(pBt->usableSize, finSize) ){ + finSize--; + } + } + TRACE(("AUTOVACUUM: Begin (db size %d->%d)\n", origSize, finSize)); + + /* Variable 'finSize' will be the size of the file in pages after + ** the auto-vacuum has completed (the current file size minus the number + ** of pages on the free list). Loop through the pages that lie beyond + ** this mark, and if they are not already on the free list, move them + ** to a free page earlier in the file (somewhere before finSize). + */ + for( iDbPage=finSize+1; iDbPage<=origSize; iDbPage++ ){ + /* If iDbPage is a pointer map page, or the pending-byte page, skip it. */ + if( PTRMAP_ISPAGE(pgsz, iDbPage) || iDbPage==PENDING_BYTE_PAGE(pBt) ){ + continue; + } + + rc = ptrmapGet(pBt, iDbPage, &eType, &iPtrPage); + if( rc!=SQLITE_OK ) goto autovacuum_out; + if( eType==PTRMAP_ROOTPAGE ){ + rc = SQLITE_CORRUPT; + goto autovacuum_out; + } + + /* If iDbPage is free, do not swap it. */ + if( eType==PTRMAP_FREEPAGE ){ + continue; + } + rc = getPage(pBt, iDbPage, &pDbMemPage); + if( rc!=SQLITE_OK ) goto autovacuum_out; + + /* Find the next page in the free-list that is not already at the end + ** of the file. A page can be pulled off the free list using the + ** allocatePage() routine. + */ + do{ + if( pFreeMemPage ){ + releasePage(pFreeMemPage); + pFreeMemPage = 0; + } + rc = allocatePage(pBt, &pFreeMemPage, &iFreePage, 0, 0); + if( rc!=SQLITE_OK ){ + releasePage(pDbMemPage); + goto autovacuum_out; + } + assert( iFreePage<=origSize ); + }while( iFreePage>finSize ); + releasePage(pFreeMemPage); + pFreeMemPage = 0; + + rc = relocatePage(pBt, pDbMemPage, eType, iPtrPage, iFreePage); + releasePage(pDbMemPage); + if( rc!=SQLITE_OK ) goto autovacuum_out; + } + + /* The entire free-list has been swapped to the end of the file. So + ** truncate the database file to finSize pages and consider the + ** free-list empty. + */ + rc = sqlite3pager_write(pBt->pPage1->aData); + if( rc!=SQLITE_OK ) goto autovacuum_out; + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + if( rc!=SQLITE_OK ) goto autovacuum_out; + *nTrunc = finSize; + +autovacuum_out: + assert( nRef==*sqlite3pager_stats(pPager) ); + if( rc!=SQLITE_OK ){ + sqlite3pager_rollback(pPager); + } + return rc; +} +#endif + /* ** Commit the transaction currently in progress. ** @@ -1381,25 +1965,6 @@ static int countWriteCursors(Btree *pBt){ } #endif -#if 0 -/* -** Invalidate all cursors -*/ -static void invalidateCursors(Btree *pBt){ - BtCursor *pCur; - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - MemPage *pPage = pCur->pPage; - if( pPage /* && !pPage->isInit */ ){ - pageIntegrity(pPage); - releasePage(pPage); - pCur->pPage = 0; - pCur->isValid = 0; - pCur->status = SQLITE_ABORT; - } - } -} -#endif - #ifdef SQLITE_TEST /* ** Print debugging information about all cursors to standard output. @@ -1584,7 +2149,7 @@ int sqlite3BtreeCursor( } } if( pBt->pPage1==0 ){ - rc = lockBtree(pBt); + rc = lockBtreeWithRetry(pBt); if( rc!=SQLITE_OK ){ return rc; } @@ -1595,12 +2160,11 @@ int sqlite3BtreeCursor( goto create_cursor_exception; } pCur->pgnoRoot = (Pgno)iTable; + pCur->pPage = 0; /* For exit-handler, in case getAndInitPage() fails. */ if( iTable==1 && sqlite3pager_pagecount(pBt->pPager)==0 ){ rc = SQLITE_EMPTY; - pCur->pPage = 0; goto create_cursor_exception; } - pCur->pPage = 0; /* For exit-handler, in case getAndInitPage() fails. */ rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0); if( rc!=SQLITE_OK ){ goto create_cursor_exception; @@ -1618,7 +2182,6 @@ int sqlite3BtreeCursor( pCur->pPrev = 0; pBt->pCursor = pCur; pCur->isValid = 0; - pCur->status = SQLITE_OK; *ppCur = pCur; return SQLITE_OK; @@ -1845,10 +2408,11 @@ static int getPayload( ** the available payload. */ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - if( pCur->isValid==0 ){ - return pCur->status; - } + assert( pCur->isValid ); assert( pCur->pPage!=0 ); + if( pCur->pPage->intKey ){ + return SQLITE_CORRUPT; + } assert( pCur->pPage->intKey==0 ); assert( pCur->idx>=0 && pCur->idxpPage->nCell ); return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); @@ -1864,9 +2428,7 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ ** the available payload. */ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - if( !pCur->isValid ){ - return pCur->status ? pCur->status : SQLITE_INTERNAL; - } + assert( pCur->isValid ); assert( pCur->pPage!=0 ); assert( pCur->idx>=0 && pCur->idxpPage->nCell ); return getPayload(pCur, offset, amt, pBuf, 1); @@ -2104,9 +2666,6 @@ static int moveToRightmost(BtCursor *pCur){ */ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ int rc; - if( pCur->status ){ - return pCur->status; - } rc = moveToRoot(pCur); if( rc ) return rc; if( pCur->isValid==0 ){ @@ -2126,9 +2685,6 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ */ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ int rc; - if( pCur->status ){ - return pCur->status; - } rc = moveToRoot(pCur); if( rc ) return rc; if( pCur->isValid==0 ){ @@ -2171,10 +2727,6 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ */ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ int rc; - - if( pCur->status ){ - return pCur->status; - } rc = moveToRoot(pCur); if( rc ) return rc; assert( pCur->pPage ); @@ -2184,13 +2736,16 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, i64 nKey, int *pRes){ assert( pCur->pPage->nCell==0 ); return SQLITE_OK; } - for(;;){ + for(;;){ int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; + if( !pPage->intKey && pKey==0 ){ + return SQLITE_CORRUPT; + } pageIntegrity(pPage); while( lwr<=upr ){ void *pCellKey; @@ -2288,6 +2843,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ } assert( pPage->isInit ); assert( pCur->idxnCell ); + pCur->idx++; pCur->info.nSize = 0; if( pCur->idx>=pPage->nCell ){ @@ -2337,6 +2893,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ *pRes = 1; return SQLITE_OK; } + pPage = pCur->pPage; assert( pPage->isInit ); assert( pCur->idx>=0 ); @@ -2357,7 +2914,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ } pCur->idx--; pCur->info.nSize = 0; - if( pPage->leafData ){ + if( pPage->leafData && !pPage->leaf ){ rc = sqlite3BtreePrevious(pCur, pRes); }else{ rc = SQLITE_OK; @@ -2367,19 +2924,6 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ return rc; } -/* -** The TRACE macro will print high-level status information about the -** btree operation when the global variable sqlite3_btree_trace is -** enabled. -*/ -#if SQLITE_TEST -# define TRACE(X) if( sqlite3_btree_trace )\ - { sqlite3DebugPrintf X; fflush(stdout); } -#else -# define TRACE(X) -#endif -int sqlite3_btree_trace=0; /* True to enable tracing */ - /* ** Allocate a new page from the database file. ** @@ -2396,8 +2940,18 @@ int sqlite3_btree_trace=0; /* True to enable tracing */ ** locate a page close to the page number "nearby". This can be used in an ** attempt to keep related pages close to each other in the database file, ** which in turn can make database access faster. +** +** If the "exact" parameter is not 0, and the page-number nearby exists +** anywhere on the free-list, then it is guarenteed to be returned. This +** is only used by auto-vacuum databases when allocating a new table. */ -static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno nearby){ +static int allocatePage( + Btree *pBt, + MemPage **ppPage, + Pgno *pPgno, + Pgno nearby, + u8 exact +){ MemPage *pPage1; int rc; int n; /* Number of pages on the freelist */ @@ -2407,72 +2961,200 @@ static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno nearby){ n = get4byte(&pPage1->aData[36]); if( n>0 ){ /* There are pages on the freelist. Reuse one of those pages. */ - MemPage *pTrunk; + MemPage *pTrunk = 0; + Pgno iTrunk; + MemPage *pPrevTrunk = 0; + u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ + + /* If the 'exact' parameter was true and a query of the pointer-map + ** shows that the page 'nearby' is somewhere on the free-list, then + ** the entire-list will be searched for that page. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( exact ){ + u8 eType; + assert( nearby>0 ); + assert( pBt->autoVacuum ); + rc = ptrmapGet(pBt, nearby, &eType, 0); + if( rc ) return rc; + if( eType==PTRMAP_FREEPAGE ){ + searchList = 1; + } + *pPgno = nearby; + } +#endif + + /* Decrement the free-list count by 1. Set iTrunk to the index of the + ** first free-list trunk page. iPrevTrunk is initially 1. + */ rc = sqlite3pager_write(pPage1->aData); if( rc ) return rc; put4byte(&pPage1->aData[36], n-1); - rc = getPage(pBt, get4byte(&pPage1->aData[32]), &pTrunk); - if( rc ) return rc; - rc = sqlite3pager_write(pTrunk->aData); - if( rc ){ - releasePage(pTrunk); - return rc; - } - k = get4byte(&pTrunk->aData[4]); - if( k==0 ){ - /* The trunk has no leaves. So extract the trunk page itself and - ** use it as the newly allocated page */ - *pPgno = get4byte(&pPage1->aData[32]); - memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); - *ppPage = pTrunk; - TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); - }else if( k>pBt->usableSize/4 - 8 ){ - /* Value of k is out of range. Database corruption */ - return SQLITE_CORRUPT; /* bkpt-CORRUPT */ - }else{ - /* Extract a leaf from the trunk */ - int closest; - unsigned char *aData = pTrunk->aData; - if( nearby>0 ){ - int i, dist; - closest = 0; - dist = get4byte(&aData[8]) - nearby; - if( dist<0 ) dist = -dist; - for(i=1; iaData[0]); }else{ - closest = 0; + iTrunk = get4byte(&pPage1->aData[32]); } - *pPgno = get4byte(&aData[8+closest*4]); - if( *pPgno>sqlite3pager_pagecount(pBt->pPager) ){ - /* Free page off the end of the file */ + rc = getPage(pBt, iTrunk, &pTrunk); + if( rc ){ + releasePage(pPrevTrunk); + return rc; + } + + /* TODO: This should move to after the loop? */ + rc = sqlite3pager_write(pTrunk->aData); + if( rc ){ + releasePage(pTrunk); + releasePage(pPrevTrunk); + return rc; + } + + k = get4byte(&pTrunk->aData[4]); + if( k==0 && !searchList ){ + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly + ** allocated page */ + assert( pPrevTrunk==0 ); + *pPgno = iTrunk; + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + *ppPage = pTrunk; + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); + }else if( k>pBt->usableSize/4 - 8 ){ + /* Value of k is out of range. Database corruption */ return SQLITE_CORRUPT; /* bkpt-CORRUPT */ +#ifndef SQLITE_OMIT_AUTOVACUUM + }else if( searchList && nearby==iTrunk ){ + /* The list is being searched and this trunk page is the page + ** to allocate, regardless of whether it has leaves. + */ + assert( *pPgno==iTrunk ); + *ppPage = pTrunk; + searchList = 0; + if( k==0 ){ + if( !pPrevTrunk ){ + memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); + }else{ + memcpy(&pPrevTrunk->aData[0], &pTrunk->aData[0], 4); + } + }else{ + /* The trunk page is required by the caller but it contains + ** pointers to free-list leaves. The first leaf becomes a trunk + ** page in this case. + */ + MemPage *pNewTrunk; + Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); + rc = getPage(pBt, iNewTrunk, &pNewTrunk); + if( rc!=SQLITE_OK ){ + releasePage(pTrunk); + releasePage(pPrevTrunk); + return rc; + } + rc = sqlite3pager_write(pNewTrunk->aData); + if( rc!=SQLITE_OK ){ + releasePage(pNewTrunk); + releasePage(pTrunk); + releasePage(pPrevTrunk); + return rc; + } + memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4); + put4byte(&pNewTrunk->aData[4], k-1); + memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); + if( !pPrevTrunk ){ + put4byte(&pPage1->aData[32], iNewTrunk); + }else{ + put4byte(&pPrevTrunk->aData[0], iNewTrunk); + } + releasePage(pNewTrunk); + } + pTrunk = 0; + TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); +#endif + }else{ + /* Extract a leaf from the trunk */ + int closest; + Pgno iPage; + unsigned char *aData = pTrunk->aData; + if( nearby>0 ){ + int i, dist; + closest = 0; + dist = get4byte(&aData[8]) - nearby; + if( dist<0 ) dist = -dist; + for(i=1; isqlite3pager_pagecount(pBt->pPager) ){ + /* Free page off the end of the file */ + return SQLITE_CORRUPT; /* bkpt-CORRUPT */ + } + TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" + ": %d more free pages\n", + *pPgno, closest+1, k, pTrunk->pgno, n-1)); + if( closestaData); + rc = sqlite3pager_write((*ppPage)->aData); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } + } + searchList = 0; + } } - TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d: %d more free pages\n", - *pPgno, closest+1, k, pTrunk->pgno, n-1)); - if( closestaData); - rc = sqlite3pager_write((*ppPage)->aData); - } - } + releasePage(pPrevTrunk); + }while( searchList ); + releasePage(pTrunk); }else{ /* There are no pages on the freelist, so create a new page at the ** end of the file */ *pPgno = sqlite3pager_pagecount(pBt->pPager) + 1; + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum && PTRMAP_ISPAGE(pBt->usableSize, *pPgno) ){ + /* If *pPgno refers to a pointer-map page, allocate two new pages + ** at the end of the file instead of one. The first allocated page + ** becomes a new pointer-map page, the second is used by the caller. + */ + TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); + (*pPgno)++; + } +#endif + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); rc = getPage(pBt, *pPgno, ppPage); if( rc ) return rc; rc = sqlite3pager_write((*ppPage)->aData); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); + } TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); } + + assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); return rc; } @@ -2498,6 +3180,16 @@ static int freePage(MemPage *pPage){ n = get4byte(&pPage1->aData[36]); put4byte(&pPage1->aData[36], n+1); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, write an entry in the pointer-map + ** to indicate that the page is free. + */ + if( pBt->autoVacuum ){ + rc = ptrmapPut(pBt, pPage->pgno, PTRMAP_FREEPAGE, 0); + if( rc ) return rc; + } +#endif + if( n==0 ){ /* This is the first free page */ rc = sqlite3pager_write(pPage->aData); @@ -2552,12 +3244,15 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ ovflPgno = get4byte(&pCell[info.iOverflow]); while( ovflPgno!=0 ){ MemPage *pOvfl; + if( ovflPgno>sqlite3pager_pagecount(pBt->pPager) ){ + return SQLITE_CORRUPT; + } rc = getPage(pBt, ovflPgno, &pOvfl); if( rc ) return rc; ovflPgno = get4byte(pOvfl->aData); rc = freePage(pOvfl); - if( rc ) return rc; sqlite3pager_unref(pOvfl->aData); + if( rc ) return rc; } return SQLITE_OK; } @@ -2628,10 +3323,23 @@ static int fillInCell( while( nPayload>0 ){ if( spaceLeft==0 ){ - rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl); +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno pgnoPtrmap = pgnoOvfl; /* Overflow page pointer-map entry page */ +#endif + rc = allocatePage(pBt, &pOvfl, &pgnoOvfl, pgnoOvfl, 0); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If the database supports auto-vacuum, and the second or subsequent + ** overflow page is being allocated, add an entry to the pointer-map + ** for that page now. The entry for the first overflow page will be + ** added later, by the insertCell() routine. + */ + if( pBt->autoVacuum && pgnoPtrmap!=0 && rc==SQLITE_OK ){ + rc = ptrmapPut(pBt, pgnoOvfl, PTRMAP_OVERFLOW2, pgnoPtrmap); + } +#endif if( rc ){ releasePage(pToRelease); - clearCell(pPage, pCell); + /* clearCell(pPage, pCell); */ return rc; } put4byte(pPrior, pgnoOvfl); @@ -2665,15 +3373,15 @@ static int fillInCell( ** given in the second argument so that MemPage.pParent holds the ** pointer in the third argument. */ -static void reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ +static int reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ MemPage *pThis; unsigned char *aData; - if( pgno==0 ) return; + if( pgno==0 ) return SQLITE_OK; assert( pBt->pPager!=0 ); aData = sqlite3pager_lookup(pBt->pPager, pgno); if( aData ){ - pThis = (MemPage*)&aData[pBt->pageSize]; + pThis = (MemPage*)&aData[pBt->psAligned]; assert( pThis->aData==aData ); if( pThis->isInit ){ if( pThis->pParent!=pNewParent ){ @@ -2685,8 +3393,17 @@ static void reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ } sqlite3pager_unref(aData); } + +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + return ptrmapPut(pBt, pgno, PTRMAP_BTREE, pNewParent->pgno); + } +#endif + return SQLITE_OK; } + + /* ** Change the pParent pointer of all children of pPage to point back ** to pPage. @@ -2697,17 +3414,26 @@ static void reparentPage(Btree *pBt, Pgno pgno, MemPage *pNewParent, int idx){ ** This routine gets called after you memcpy() one page into ** another. */ -static void reparentChildPages(MemPage *pPage){ +static int reparentChildPages(MemPage *pPage){ int i; - Btree *pBt; + Btree *pBt = pPage->pBt; + int rc = SQLITE_OK; + + if( pPage->leaf ) return SQLITE_OK; - if( pPage->leaf ) return; - pBt = pPage->pBt; for(i=0; inCell; i++){ - reparentPage(pBt, get4byte(findCell(pPage,i)), pPage, i); + u8 *pCell = findCell(pPage, i); + if( !pPage->leaf ){ + rc = reparentPage(pBt, get4byte(pCell), pPage, i); + if( rc!=SQLITE_OK ) return rc; + } } - reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), pPage, i); - pPage->idxShift = 0; + if( !pPage->leaf ){ + rc = reparentPage(pBt, get4byte(&pPage->aData[pPage->hdrOffset+8]), + pPage, i); + pPage->idxShift = 0; + } + return rc; } /* @@ -2753,13 +3479,19 @@ static void dropCell(MemPage *pPage, int idx, int sz){ ** in pTemp or the original pCell) and also record its index. ** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. +** +** If nSkip is non-zero, then do not copy the first nSkip bytes of the +** cell. The caller will overwrite them after this function returns. If +** nSkip is non-zero, then pCell may not point to an invalid memory location +** (but pCell+nSkip is always valid). */ -static void insertCell( +static int insertCell( MemPage *pPage, /* Page into which we are copying */ int i, /* New cell becomes the i-th cell of the page */ u8 *pCell, /* Content of the new cell */ int sz, /* Bytes of content in pCell */ - u8 *pTemp /* Temp storage space for pCell, if needed */ + u8 *pTemp, /* Temp storage space for pCell, if needed */ + u8 nSkip /* Do not write the first nSkip bytes of the cell */ ){ int idx; /* Where to write new cell content in data[] */ int j; /* Loop counter */ @@ -2776,7 +3508,7 @@ static void insertCell( assert( sqlite3pager_iswriteable(pPage->aData) ); if( pPage->nOverflow || sz+2>pPage->nFree ){ if( pTemp ){ - memcpy(pTemp, pCell, sz); + memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); pCell = pTemp; } j = pPage->nOverflow++; @@ -2792,7 +3524,8 @@ static void insertCell( end = cellOffset + 2*pPage->nCell + 2; ins = cellOffset + 2*i; if( end > top - sz ){ - defragmentPage(pPage); + int rc = defragmentPage(pPage); + if( rc!=SQLITE_OK ) return rc; top = get2byte(&data[hdr+5]); assert( end + sz <= top ); } @@ -2801,7 +3534,7 @@ static void insertCell( assert( end <= get2byte(&data[hdr+5]) ); pPage->nCell++; pPage->nFree -= 2; - memcpy(&data[idx], pCell, sz); + memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){ ptr[0] = ptr[-2]; ptr[1] = ptr[-1]; @@ -2810,7 +3543,23 @@ static void insertCell( put2byte(&data[hdr+3], pPage->nCell); pPage->idxShift = 1; pageIntegrity(pPage); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pPage->pBt->autoVacuum ){ + /* The cell may contain a pointer to an overflow page. If so, write + ** the entry for the overflow page into the pointer map. + */ + CellInfo info; + parseCellPtr(pPage, pCell, &info); + if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ + Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); + int rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno); + if( rc!=SQLITE_OK ) return rc; + } + } +#endif } + + return SQLITE_OK; } /* @@ -2855,14 +3604,6 @@ static void assemblePage( pPage->nCell = nCell; } -/* -** GCC does not define the offsetof() macro so we'll have to do it -** ourselves. -*/ -#ifndef offsetof -#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) -#endif - /* ** The following parameters determine how many adjacent pages get involved ** in a balancing operation. NN is the number of neighbors on either side @@ -2879,7 +3620,110 @@ static void assemblePage( #define NB (NN*2+1) /* Total pages involved in the balance */ /* Forward reference */ -static int balance(MemPage*); +static int balance(MemPage*, int); + +#ifndef SQLITE_OMIT_QUICKBALANCE +/* +** This version of balance() handles the common special case where +** a new entry is being inserted on the extreme right-end of the +** tree, in other words, when the new entry will become the largest +** entry in the tree. +** +** Instead of trying balance the 3 right-most leaf pages, just add +** a new page to the right-hand side and put the one new entry in +** that page. This leaves the right side of the tree somewhat +** unbalanced. But odds are that we will be inserting new entries +** at the end soon afterwards so the nearly empty page will quickly +** fill up. On average. +** +** pPage is the leaf page which is the right-most page in the tree. +** pParent is its parent. pPage must have a single overflow entry +** which is also the right-most entry on the page. +*/ +static int balance_quick(MemPage *pPage, MemPage *pParent){ + int rc; + MemPage *pNew; + Pgno pgnoNew; + u8 *pCell; + int szCell; + CellInfo info; + Btree *pBt = pPage->pBt; + int parentIdx = pParent->nCell; /* pParent new divider cell index */ + int parentSize; /* Size of new divider cell */ + u8 parentCell[64]; /* Space for the new divider cell */ + + /* Allocate a new page. Insert the overflow cell from pPage + ** into it. Then remove the overflow cell from pPage. + */ + rc = allocatePage(pBt, &pNew, &pgnoNew, 0, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + pCell = pPage->aOvfl[0].pCell; + szCell = cellSizePtr(pPage, pCell); + zeroPage(pNew, pPage->aData[0]); + assemblePage(pNew, 1, &pCell, &szCell); + pPage->nOverflow = 0; + + /* Set the parent of the newly allocated page to pParent. */ + pNew->pParent = pParent; + sqlite3pager_ref(pParent->aData); + + /* pPage is currently the right-child of pParent. Change this + ** so that the right-child is the new page allocated above and + ** pPage is the next-to-right child. + */ + assert( pPage->nCell>0 ); + parseCellPtr(pPage, findCell(pPage, pPage->nCell-1), &info); + rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, &parentSize); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( parentSize<64 ); + rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4); + if( rc!=SQLITE_OK ){ + return rc; + } + put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno); + put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. + */ + if( pBt->autoVacuum ){ + rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapPutOvfl(pNew, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + } +#endif + + /* Release the reference to the new page and balance the parent page, + ** in case the divider cell inserted caused it to become overfull. + */ + releasePage(pNew); + return balance(pParent, 0); +} +#endif /* SQLITE_OMIT_QUICKBALANCE */ + +/* +** The ISAUTOVACUUM macro is used within balance_nonroot() to determine +** if the database supports auto-vacuum or not. Because it is used +** within an expression that is an argument to another macro +** (sqliteMallocRaw), it is not possible to use conditional compilation. +** So, this macro is defined instead. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +#define ISAUTOVACUUM (pBt->autoVacuum) +#else +#define ISAUTOVACUUM 0 +#endif /* ** This routine redistributes Cells on pPage and up to NN*2 siblings @@ -2941,6 +3785,9 @@ static int balance_nonroot(MemPage *pPage){ int *szCell; /* Local size of all cells in apCell[] */ u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ u8 *aSpace; /* Space to hold copies of dividers cells */ +#ifndef SQLITE_OMIT_AUTOVACUUM + u8 *aFrom = 0; +#endif /* ** Find the parent page. @@ -2953,6 +3800,31 @@ static int balance_nonroot(MemPage *pPage){ assert( pParent ); TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); +#ifndef SQLITE_OMIT_QUICKBALANCE + /* + ** A special case: If a new entry has just been inserted into a + ** table (that is, a btree with integer keys and all data at the leaves) + ** an the new entry is the right-most entry in the tree (it has the + ** largest key) then use the special balance_quick() routine for + ** balancing. balance_quick() is much faster and results in a tighter + ** packing of data in the common case. + */ + if( pPage->leaf && + pPage->intKey && + pPage->leafData && + pPage->nOverflow==1 && + pPage->aOvfl[0].idx==pPage->nCell && + pPage->pParent->pgno!=1 && + get4byte(&pParent->aData[pParent->hdrOffset+8])==pPage->pgno + ){ + /* + ** TODO: Check the siblings to the left of pPage. It may be that + ** they are not full and no new page is required. + */ + return balance_quick(pPage, pParent); + } +#endif + /* ** Allocate space for memory structures */ @@ -2960,7 +3832,8 @@ static int balance_nonroot(MemPage *pPage){ apCell = sqliteMallocRaw( (mxCellPerPage+2)*NB*(sizeof(u8*)+sizeof(int)) + sizeof(MemPage)*NB - + pBt->pageSize*(5+NB) + + pBt->psAligned*(5+NB) + + (ISAUTOVACUUM ? (mxCellPerPage+2)*NN*2 : 0) ); if( apCell==0 ){ return SQLITE_NOMEM; @@ -2968,9 +3841,14 @@ static int balance_nonroot(MemPage *pPage){ szCell = (int*)&apCell[(mxCellPerPage+2)*NB]; aCopy[0] = (u8*)&szCell[(mxCellPerPage+2)*NB]; for(i=1; ipageSize+sizeof(MemPage)]; + aCopy[i] = &aCopy[i-1][pBt->psAligned+sizeof(MemPage)]; } - aSpace = &aCopy[NB-1][pBt->pageSize+sizeof(MemPage)]; + aSpace = &aCopy[NB-1][pBt->psAligned+sizeof(MemPage)]; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + aFrom = &aSpace[5*pBt->psAligned]; + } +#endif /* ** Find the cell in the parent page whose left child points back @@ -3041,10 +3919,10 @@ static int balance_nonroot(MemPage *pPage){ ** process of being overwritten. */ for(i=0; ipageSize]; - p->aData = &((u8*)p)[-pBt->pageSize]; - memcpy(p->aData, apOld[i]->aData, pBt->pageSize + sizeof(MemPage)); - p->aData = &((u8*)p)[-pBt->pageSize]; + MemPage *p = apCopy[i] = (MemPage*)&aCopy[i][pBt->psAligned]; + p->aData = &((u8*)p)[-pBt->psAligned]; + memcpy(p->aData, apOld[i]->aData, pBt->psAligned + sizeof(MemPage)); + p->aData = &((u8*)p)[-pBt->psAligned]; } /* @@ -3072,6 +3950,18 @@ static int balance_nonroot(MemPage *pPage){ for(j=0; jautoVacuum ){ + int a; + aFrom[nCell] = i; + for(a=0; anOverflow; a++){ + if( pOld->aOvfl[a].pCell==apCell[nCell] ){ + aFrom[nCell] = 0xFF; + break; + } + } + } +#endif nCell++; } if( ipageSize*5 ); + assert( iSpace<=pBt->psAligned*5 ); memcpy(pTemp, apDiv[i], sz); apCell[nCell] = pTemp+leafCorrection; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + aFrom[nCell] = 0xFF; + } +#endif dropCell(pParent, nxDiv, sz); szCell[nCell] -= leafCorrection; assert( get4byte(pTemp)==pgnoOld[i] ); @@ -3179,9 +4074,10 @@ static int balance_nonroot(MemPage *pPage){ pNew = apNew[i] = apOld[i]; pgnoNew[i] = pgnoOld[i]; apOld[i] = 0; - sqlite3pager_write(pNew->aData); + rc = sqlite3pager_write(pNew->aData); + if( rc ) goto balance_cleanup; }else{ - rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1]); + rc = allocatePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0); if( rc ) goto balance_cleanup; apNew[i] = pNew; } @@ -3243,19 +4139,42 @@ static int balance_nonroot(MemPage *pPage){ nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); - /* ** Evenly distribute the data in apCell[] across the new pages. ** Insert divider cells into pParent as necessary. */ j = 0; for(i=0; ipgno==pgnoNew[i] ); assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]); - j = cntNew[i]; assert( pNew->nCell>0 ); assert( pNew->nOverflow==0 ); + +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If this is an auto-vacuum database, update the pointer map entries + ** that point to the siblings that were rearranged. These can be: left + ** children of cells, the right-child of the page, or overflow pages + ** pointed to by cells. + */ + if( pBt->autoVacuum ){ + for(k=j; kpgno!=pNew->pgno ){ + rc = ptrmapPutOvfl(pNew, k-j); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } + } + } +#endif + + j = cntNew[i]; + + /* If the sibling page assembled above was not the right-most sibling, + ** insert a divider cell into the parent page. + */ if( iaData[8], pCell, 4); pTemp = 0; }else if( leafData ){ + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of + ** the sibling-page assembled above only. + */ CellInfo info; j--; parseCellPtr(pNew, apCell[j], &info); pCell = &aSpace[iSpace]; fillInCell(pParent, pCell, 0, info.nKey, 0, 0, &sz); iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); + assert( iSpace<=pBt->psAligned*5 ); pTemp = 0; }else{ pCell -= 4; pTemp = &aSpace[iSpace]; iSpace += sz; - assert( iSpace<=pBt->pageSize*5 ); + assert( iSpace<=pBt->psAligned*5 ); } - insertCell(pParent, nxDiv, pCell, sz, pTemp); + rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); + if( rc!=SQLITE_OK ) goto balance_cleanup; put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* If this is an auto-vacuum database, and not a leaf-data tree, + ** then update the pointer map with an entry for the overflow page + ** that the cell just inserted points to (if any). + */ + if( pBt->autoVacuum && !leafData ){ + rc = ptrmapPutOvfl(pParent, nxDiv); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } +#endif j++; nxDiv++; } @@ -3303,19 +4240,21 @@ static int balance_nonroot(MemPage *pPage){ ** Reparent children of all cells. */ for(i=0; iisInit ); /* assert( pPage->isInit ); // No! pPage might have been added to freelist */ /* pageIntegrity(pPage); // No! pPage might have been added to freelist */ - rc = balance(pParent); + rc = balance(pParent, 0); /* ** Cleanup before returning. @@ -3390,6 +4329,9 @@ static int balance_shallower(MemPage *pPage){ szCell[i] = cellSizePtr(pChild, apCell[i]); } assemblePage(pPage, pChild->nCell, apCell, szCell); + /* Copy the right-pointer of the child to the parent. */ + put4byte(&pPage->aData[pPage->hdrOffset+8], + get4byte(&pChild->aData[pChild->hdrOffset+8])); freePage(pChild); TRACE(("BALANCE: child %d transfer to page 1\n", pChild->pgno)); }else{ @@ -3407,7 +4349,20 @@ static int balance_shallower(MemPage *pPage){ TRACE(("BALANCE: transfer child %d into root %d\n", pChild->pgno, pPage->pgno)); } - reparentChildPages(pPage); + rc = reparentChildPages(pPage); + assert( pPage->nOverflow==0 ); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + int i; + for(i=0; inCell; i++){ + rc = ptrmapPutOvfl(pPage, i); + if( rc!=SQLITE_OK ){ + goto end_shallow_balance; + } + } + } +#endif + if( rc!=SQLITE_OK ) goto end_shallow_balance; releasePage(pChild); } end_shallow_balance: @@ -3439,7 +4394,7 @@ static int balance_deeper(MemPage *pPage){ assert( pPage->pParent==0 ); assert( pPage->nOverflow>0 ); pBt = pPage->pBt; - rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno); + rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); if( rc ) return rc; assert( sqlite3pager_iswriteable(pChild->aData) ); usableSize = pBt->usableSize; @@ -3449,8 +4404,9 @@ static int balance_deeper(MemPage *pPage){ cdata = pChild->aData; memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr); memcpy(&cdata[brk], &data[brk], usableSize-brk); + assert( pChild->isInit==0 ); rc = initPage(pChild, pPage); - if( rc ) return rc; + if( rc ) goto balancedeeper_out; memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0])); pChild->nOverflow = pPage->nOverflow; if( pChild->nOverflow ){ @@ -3460,7 +4416,22 @@ static int balance_deeper(MemPage *pPage){ zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + int i; + rc = ptrmapPut(pBt, pChild->pgno, PTRMAP_BTREE, pPage->pgno); + if( rc ) goto balancedeeper_out; + for(i=0; inCell; i++){ + rc = ptrmapPutOvfl(pChild, i); + if( rc!=SQLITE_OK ){ + return rc; + } + } + } +#endif rc = balance_nonroot(pChild); + +balancedeeper_out: releasePage(pChild); return rc; } @@ -3469,17 +4440,18 @@ static int balance_deeper(MemPage *pPage){ ** Decide if the page pPage needs to be balanced. If balancing is ** required, call the appropriate balancing routine. */ -static int balance(MemPage *pPage){ +static int balance(MemPage *pPage, int insert){ int rc = SQLITE_OK; if( pPage->pParent==0 ){ if( pPage->nOverflow>0 ){ rc = balance_deeper(pPage); } - if( pPage->nCell==0 ){ + if( rc==SQLITE_OK && pPage->nCell==0 ){ rc = balance_shallower(pPage); } }else{ - if( pPage->nOverflow>0 || pPage->nFree>pPage->pBt->usableSize*2/3 ){ + if( pPage->nOverflow>0 || + (!insert && pPage->nFree>pPage->pBt->usableSize*2/3) ){ rc = balance_nonroot(pPage); } } @@ -3535,9 +4507,6 @@ int sqlite3BtreeInsert( unsigned char *oldCell; unsigned char *newCell = 0; - if( pCur->status ){ - return pCur->status; /* A rollback destroyed this cursor */ - } if( pBt->inTrans!=TRANS_WRITE ){ /* Must start a transaction before doing an insert */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; @@ -3584,11 +4553,14 @@ int sqlite3BtreeInsert( }else{ assert( pPage->leaf ); } - insertCell(pPage, pCur->idx, newCell, szNew, 0); - rc = balance(pPage); + rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0); + if( rc!=SQLITE_OK ) goto end_insert; + rc = balance(pPage, 1); /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ - moveToRoot(pCur); + if( rc==SQLITE_OK ){ + moveToRoot(pCur); + } end_insert: sqliteFree(newCell); return rc; @@ -3606,9 +4578,6 @@ int sqlite3BtreeDelete(BtCursor *pCur){ Btree *pBt = pCur->pBt; assert( pPage->isInit ); - if( pCur->status ){ - return pCur->status; /* A rollback destroyed this cursor */ - } if( pBt->inTrans!=TRANS_WRITE ){ /* Must start a transaction before doing a delete */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; @@ -3625,11 +4594,18 @@ int sqlite3BtreeDelete(BtCursor *pCur){ } rc = sqlite3pager_write(pPage->aData); if( rc ) return rc; + + /* Locate the cell within it's page and leave pCell pointing to the + ** data. The clearCell() call frees any overflow pages associated with the + ** cell. The cell itself is still intact. + */ pCell = findCell(pPage, pCur->idx); if( !pPage->leaf ){ pgnoChild = get4byte(pCell); } - clearCell(pPage, pCell); + rc = clearCell(pPage, pCell); + if( rc ) return rc; + if( !pPage->leaf ){ /* ** The entry we are about to delete is not a leaf so if we do not @@ -3642,7 +4618,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){ unsigned char *pNext; int szNext; int notUsed; - unsigned char *tempCell; + unsigned char *tempCell = 0; assert( !pPage->leafData ); getTempCursor(pCur, &leafCur); rc = sqlite3BtreeNext(&leafCur, ¬Used); @@ -3650,33 +4626,44 @@ int sqlite3BtreeDelete(BtCursor *pCur){ if( rc!=SQLITE_NOMEM ){ rc = SQLITE_CORRUPT; /* bkpt-CORRUPT */ } - return rc; } - rc = sqlite3pager_write(leafCur.pPage->aData); - if( rc ) return rc; - TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", - pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno)); - dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); - pNext = findCell(leafCur.pPage, leafCur.idx); - szNext = cellSizePtr(leafCur.pPage, pNext); - assert( MX_CELL_SIZE(pBt)>=szNext+4 ); - tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) ); - if( tempCell==0 ) return SQLITE_NOMEM; - insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell); - put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); - rc = balance(pPage); + if( rc==SQLITE_OK ){ + rc = sqlite3pager_write(leafCur.pPage->aData); + } + if( rc==SQLITE_OK ){ + TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", + pCur->pgnoRoot, pPage->pgno, leafCur.pPage->pgno)); + dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); + pNext = findCell(leafCur.pPage, leafCur.idx); + szNext = cellSizePtr(leafCur.pPage, pNext); + assert( MX_CELL_SIZE(pBt)>=szNext+4 ); + tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) ); + if( tempCell==0 ){ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell, 0); + } + if( rc==SQLITE_OK ){ + put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); + rc = balance(pPage, 0); + } + if( rc==SQLITE_OK ){ + dropCell(leafCur.pPage, leafCur.idx, szNext); + rc = balance(leafCur.pPage, 0); + } sqliteFree(tempCell); - if( rc ) return rc; - dropCell(leafCur.pPage, leafCur.idx, szNext); - rc = balance(leafCur.pPage); releaseTempCursor(&leafCur); }else{ TRACE(("DELETE: table=%d delete from leaf %d\n", pCur->pgnoRoot, pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); - rc = balance(pPage); + rc = balance(pPage, 0); + } + if( rc==SQLITE_OK ){ + moveToRoot(pCur); } - moveToRoot(pCur); return rc; } @@ -3699,11 +4686,107 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){ /* Must start a transaction first */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } - if( pBt->readOnly ){ - return SQLITE_READONLY; + assert( !pBt->readOnly ); + + /* It is illegal to create a table if any cursors are open on the + ** database. This is because in auto-vacuum mode the backend may + ** need to move a database page to make room for the new root-page. + ** If an open cursor was using the page a problem would occur. + */ + if( pBt->pCursor ){ + return SQLITE_LOCKED; } - rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1); + +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0); if( rc ) return rc; +#else + if( pBt->autoVacuum ){ + Pgno pgnoMove; /* Move a page here to make room for the root-page */ + MemPage *pPageMove; /* The page to move to. */ + + /* Read the value of meta[3] from the database to determine where the + ** root page of the new table should go. meta[3] is the largest root-page + ** created so far, so the new root-page is (meta[3]+1). + */ + rc = sqlite3BtreeGetMeta(pBt, 4, &pgnoRoot); + if( rc!=SQLITE_OK ) return rc; + pgnoRoot++; + + /* The new root-page may not be allocated on a pointer-map page, or the + ** PENDING_BYTE page. + */ + if( pgnoRoot==PTRMAP_PAGENO(pBt->usableSize, pgnoRoot) || + pgnoRoot==PENDING_BYTE_PAGE(pBt) ){ + pgnoRoot++; + } + assert( pgnoRoot>=3 ); + + /* Allocate a page. The page that currently resides at pgnoRoot will + ** be moved to the allocated page (unless the allocated page happens + ** to reside at pgnoRoot). + */ + rc = allocatePage(pBt, &pPageMove, &pgnoMove, pgnoRoot, 1); + if( rc!=SQLITE_OK ){ + return rc; + } + + if( pgnoMove!=pgnoRoot ){ + u8 eType; + Pgno iPtrPage; + + releasePage(pPageMove); + rc = getPage(pBt, pgnoRoot, &pRoot); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); + if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + releasePage(pRoot); + return rc; + } + assert( eType!=PTRMAP_ROOTPAGE ); + assert( eType!=PTRMAP_FREEPAGE ); + rc = sqlite3pager_write(pRoot->aData); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + rc = relocatePage(pBt, pRoot, eType, iPtrPage, pgnoMove); + releasePage(pRoot); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = getPage(pBt, pgnoRoot, &pRoot); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = sqlite3pager_write(pRoot->aData); + if( rc!=SQLITE_OK ){ + releasePage(pRoot); + return rc; + } + }else{ + pRoot = pPageMove; + } + + /* Update the pointer-map and meta-data with the new root-page number. */ + rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0); + if( rc ){ + releasePage(pRoot); + return rc; + } + rc = sqlite3BtreeUpdateMeta(pBt, 4, pgnoRoot); + if( rc ){ + releasePage(pRoot); + return rc; + } + + }else{ + rc = allocatePage(pBt, &pRoot, &pgnoRoot, 1, 0); + if( rc ) return rc; + } +#endif assert( sqlite3pager_iswriteable(pRoot->aData) ); zeroPage(pRoot, flags | PTF_LEAF); sqlite3pager_unref(pRoot->aData); @@ -3721,33 +4804,39 @@ static int clearDatabasePage( MemPage *pParent, /* Parent page. NULL for the root */ int freePageFlag /* Deallocate page if true */ ){ - MemPage *pPage; + MemPage *pPage = 0; int rc; unsigned char *pCell; int i; + if( pgno>sqlite3pager_pagecount(pBt->pPager) ){ + return SQLITE_CORRUPT; + } + rc = getAndInitPage(pBt, pgno, &pPage, pParent); - if( rc ) return rc; + if( rc ) goto cleardatabasepage_out; rc = sqlite3pager_write(pPage->aData); - if( rc ) return rc; + if( rc ) goto cleardatabasepage_out; for(i=0; inCell; i++){ pCell = findCell(pPage, i); if( !pPage->leaf ){ rc = clearDatabasePage(pBt, get4byte(pCell), pPage->pParent, 1); - if( rc ) return rc; + if( rc ) goto cleardatabasepage_out; } rc = clearCell(pPage, pCell); - if( rc ) return rc; + if( rc ) goto cleardatabasepage_out; } if( !pPage->leaf ){ rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), pPage->pParent, 1); - if( rc ) return rc; + if( rc ) goto cleardatabasepage_out; } if( freePageFlag ){ rc = freePage(pPage); }else{ zeroPage(pPage, pPage->aData[0] | PTF_LEAF); } + +cleardatabasepage_out: releasePage(pPage); return rc; } @@ -3787,29 +4876,122 @@ int sqlite3BtreeClearTable(Btree *pBt, int iTable){ ** ** This routine will fail with SQLITE_LOCKED if there are any open ** cursors on the table. +** +** If AUTOVACUUM is enabled and the page at iTable is not the last +** root page in the database file, then the last root page +** in the database file is moved into the slot formerly occupied by +** iTable and that last slot formerly occupied by the last root page +** is added to the freelist instead of iTable. In this say, all +** root pages are kept at the beginning of the database file, which +** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** page number that used to be the last root page in the file before +** the move. If no page gets moved, *piMoved is set to 0. +** The last root page is recorded in meta[3] and the value of +** meta[3] is updated by this procedure. */ -int sqlite3BtreeDropTable(Btree *pBt, int iTable){ +int sqlite3BtreeDropTable(Btree *pBt, int iTable, int *piMoved){ int rc; - MemPage *pPage; - BtCursor *pCur; + MemPage *pPage = 0; + if( pBt->inTrans!=TRANS_WRITE ){ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; } - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ - if( pCur->pgnoRoot==(Pgno)iTable ){ - return SQLITE_LOCKED; /* Cannot drop a table that has a cursor */ - } + + /* It is illegal to drop a table if any cursors are open on the + ** database. This is because in auto-vacuum mode the backend may + ** need to move another root-page to fill a gap left by the deleted + ** root page. If an open cursor was using this page a problem would + ** occur. + */ + if( pBt->pCursor ){ + return SQLITE_LOCKED; } + rc = getPage(pBt, (Pgno)iTable, &pPage); if( rc ) return rc; rc = sqlite3BtreeClearTable(pBt, iTable); - if( rc ) return rc; - if( iTable>1 ){ - rc = freePage(pPage); - }else{ - zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); + if( rc ){ + releasePage(pPage); + return rc; + } + + *piMoved = 0; + + if( iTable>1 ){ +#ifdef SQLITE_OMIT_AUTOVACUUM + rc = freePage(pPage); + releasePage(pPage); +#else + if( pBt->autoVacuum ){ + Pgno maxRootPgno; + rc = sqlite3BtreeGetMeta(pBt, 4, &maxRootPgno); + if( rc!=SQLITE_OK ){ + releasePage(pPage); + return rc; + } + + if( iTable==maxRootPgno ){ + /* If the table being dropped is the table with the largest root-page + ** number in the database, put the root page on the free list. + */ + rc = freePage(pPage); + releasePage(pPage); + if( rc!=SQLITE_OK ){ + return rc; + } + }else{ + /* The table being dropped does not have the largest root-page + ** number in the database. So move the page that does into the + ** gap left by the deleted root-page. + */ + MemPage *pMove; + releasePage(pPage); + rc = getPage(pBt, maxRootPgno, &pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = relocatePage(pBt, pMove, PTRMAP_ROOTPAGE, 0, iTable); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = getPage(pBt, maxRootPgno, &pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = freePage(pMove); + releasePage(pMove); + if( rc!=SQLITE_OK ){ + return rc; + } + *piMoved = maxRootPgno; + } + + /* Set the new 'max-root-page' value in the database header. This + ** is the old value less one, less one more if that happens to + ** be a root-page number, less one again if that is the + ** PENDING_BYTE_PAGE. + */ + maxRootPgno--; + if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){ + maxRootPgno--; + } + if( maxRootPgno==PTRMAP_PAGENO(pBt->usableSize, maxRootPgno) ){ + maxRootPgno--; + } + assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); + + rc = sqlite3BtreeUpdateMeta(pBt, 4, maxRootPgno); + }else{ + rc = freePage(pPage); + releasePage(pPage); + } +#endif + }else{ + /* If sqlite3BtreeDropTable was called on page 1. */ + zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); + releasePage(pPage); } - releasePage(pPage); return rc; } @@ -3834,9 +5016,12 @@ int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){ *pMeta = get4byte(&pP1[36 + idx*4]); sqlite3pager_unref(pP1); - /* The current implementation is unable to handle writes to an autovacuumed - ** database. So make such a database readonly. */ + /* If autovacuumed is disabled in this build but we are trying to + ** access an autovacuumed database, then make the database readonly. + */ +#ifdef SQLITE_OMIT_AUTOVACUUM if( idx==4 && *pMeta>0 ) pBt->readOnly = 1; +#endif return SQLITE_OK; } @@ -3869,12 +5054,12 @@ int sqlite3BtreeFlags(BtCursor *pCur){ return pPage ? pPage->aData[pPage->hdrOffset] : 0; } +#ifdef SQLITE_DEBUG /* ** Print a disassembly of the given page on standard output. This routine ** is used for debugging and testing only. */ -#ifdef SQLITE_TEST -int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ +static int btreePageDump(Btree *pBt, int pgno, int recursive, MemPage *pParent){ int rc; MemPage *pPage; int i, j, c; @@ -3890,7 +5075,7 @@ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ rc = getPage(pBt, (Pgno)pgno, &pPage); isInit = pPage->isInit; if( pPage->isInit==0 ){ - initPage(pPage, 0); + initPage(pPage, pParent); } if( rc ){ return rc; @@ -3960,16 +5145,19 @@ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ if( recursive && !pPage->leaf ){ for(i=0; iisInit = isInit; sqlite3pager_unref(data); fflush(stdout); return SQLITE_OK; } +int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){ + return btreePageDump(pBt, pgno, recursive, 0); +} #endif #ifdef SQLITE_TEST @@ -4058,6 +5246,7 @@ struct IntegrityCk { char *zErrMsg; /* An error message. NULL of no errors seen. */ }; +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Append a message to the error message string. */ @@ -4083,7 +5272,9 @@ static void checkAppendMsg( } sqliteFree(zMsg2); } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. @@ -4105,6 +5296,37 @@ static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ return (pCheck->anRef[iPage]++)>1; } +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Check that the entry in the pointer-map for page iChild maps to +** page iParent, pointer type ptrType. If not, append an error message +** to pCheck. +*/ +static void checkPtrmap( + IntegrityCk *pCheck, /* Integrity check context */ + Pgno iChild, /* Child page number */ + u8 eType, /* Expected pointer map type */ + Pgno iParent, /* Expected pointer map parent page number */ + char *zContext /* Context description (used for error msg) */ +){ + int rc; + u8 ePtrmapType; + Pgno iPtrmapParent; + + rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent); + if( rc!=SQLITE_OK ){ + checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild); + return; + } + + if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ + checkAppendMsg(pCheck, zContext, + "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", + iChild, eType, iParent, ePtrmapType, iPtrmapParent); + } +} +#endif + /* ** Check the integrity of the freelist or of an overflow page list. ** Verify that the number of pages on the list is N. @@ -4134,22 +5356,47 @@ static void checkList( } if( isFreeList ){ int n = get4byte(&pOvfl[4]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pCheck->pBt->autoVacuum ){ + checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext); + } +#endif if( n>pCheck->pBt->usableSize/4-8 ){ checkAppendMsg(pCheck, zContext, "freelist leaf count too big on page %d", iPage); N--; }else{ for(i=0; ipBt->autoVacuum ){ + checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext); + } +#endif + checkRef(pCheck, iFreePage, zContext); } N -= n; } } +#ifndef SQLITE_OMIT_AUTOVACUUM + else{ + /* If this database supports auto-vacuum and iPage is not the last + ** page in this overflow list, check that the pointer-map entry for + ** the following page matches iPage. + */ + if( pCheck->pBt->autoVacuum && N>0 ){ + i = get4byte(pOvfl); + checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext); + } + } +#endif iPage = get4byte(pOvfl); sqlite3pager_unref(pOvfl); } } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ +#ifndef SQLITE_OMIT_INTEGRITY_CHECK /* ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages @@ -4189,6 +5436,8 @@ static int checkTreePage( char zContext[100]; char *hit; + sprintf(zContext, "Page %d: ", iPage); + /* Check that the page exists */ cur.pBt = pBt = pCheck->pBt; @@ -4225,13 +5474,24 @@ static int checkTreePage( if( !pPage->intKey ) sz += info.nKey; if( sz>info.nLocal ){ int nPage = (sz - info.nLocal + usableSize - 5)/(usableSize - 4); - checkList(pCheck, 0, get4byte(&pCell[info.iOverflow]),nPage,zContext); + Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext); + } +#endif + checkList(pCheck, 0, pgnoOvfl, nPage, zContext); } /* Check sanity of left child page. */ if( !pPage->leaf ){ pgno = get4byte(pCell); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext); + } +#endif d2 = checkTreePage(pCheck,pgno,pPage,zContext,0,0,0,0); if( i>0 && d2!=depth ){ checkAppendMsg(pCheck, zContext, "Child page depth differs"); @@ -4242,6 +5502,11 @@ static int checkTreePage( if( !pPage->leaf ){ pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); sprintf(zContext, "On page %d at right child: ", iPage); +#ifndef SQLITE_OMIT_AUTOVACUUM + if( pBt->autoVacuum ){ + checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, 0); + } +#endif checkTreePage(pCheck, pgno, pPage, zContext,0,0,0,0); } @@ -4258,13 +5523,23 @@ static int checkTreePage( int pc = get2byte(&data[cellStart+i*2]); int size = cellSizePtr(pPage, &data[pc]); int j; - for(j=pc+size-1; j>=pc; j--) hit[j]++; + if( (pc+size-1)>=usableSize || pc<0 ){ + checkAppendMsg(pCheck, 0, + "Corruption detected in cell %d on page %d",i,iPage,0); + }else{ + for(j=pc+size-1; j>=pc; j--) hit[j]++; + } } for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i=i; j--) hit[j]++; + if( (i+size-1)>=usableSize || i<0 ){ + checkAppendMsg(pCheck, 0, + "Corruption detected in cell %d on page %d",i,iPage,0); + }else{ + for(j=i+size-1; j>=i; j--) hit[j]++; + } i = get2byte(&data[i]); } for(i=cnt=0; ipPager); - if( lockBtree(pBt)!=SQLITE_OK ){ + if( lockBtreeWithRetry(pBt)!=SQLITE_OK ){ return sqliteStrDup("Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; @@ -4315,8 +5592,13 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ return 0; } sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); + if( !sCheck.anRef ){ + unlockBtreeIfUnused(pBt); + return sqlite3MPrintf("Unable to malloc %d bytes", + (sCheck.nPage+1)*sizeof(sCheck.anRef[0])); + } for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; } - i = PENDING_BYTE/pBt->pageSize + 1; + i = PENDING_BYTE_PAGE(pBt); if( i<=sCheck.nPage ){ sCheck.anRef[i] = 1; } @@ -4331,15 +5613,34 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ */ for(i=0; iautoVacuum && aRoot[i]>1 ){ + checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0); + } +#endif checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0); } /* Make sure every page in the file is referenced */ for(i=1; i<=sCheck.nPage; i++){ +#ifdef SQLITE_OMIT_AUTOVACUUM if( sCheck.anRef[i]==0 ){ checkAppendMsg(&sCheck, 0, "Page %d is never used", i); } +#else + /* If the database supports auto-vacuum, make sure no tables contain + ** references to pointer-map pages. + */ + if( sCheck.anRef[i]==0 && + (PTRMAP_PAGENO(pBt->usableSize, i)!=i || !pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, 0, "Page %d is never used", i); + } + if( sCheck.anRef[i]!=0 && + (PTRMAP_PAGENO(pBt->usableSize, i)==i && pBt->autoVacuum) ){ + checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i); + } +#endif } /* Make sure this analysis did not leave any unref() pages @@ -4357,6 +5658,7 @@ char *sqlite3BtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ sqliteFree(sCheck.anRef); return sCheck.zErrMsg; } +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ /* ** Return the full pathname of the underlying database file. @@ -4384,6 +5686,7 @@ const char *sqlite3BtreeGetJournalname(Btree *pBt){ return sqlite3pager_journalname(pBt->pPager); } +#ifndef SQLITE_OMIT_VACUUM /* ** Copy the complete content of pBtFrom into pBtTo. A transaction ** must be active for both files. @@ -4425,6 +5728,7 @@ int sqlite3BtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){ } return rc; } +#endif /* SQLITE_OMIT_VACUUM */ /* ** Return non-zero if a transaction is active. @@ -4456,7 +5760,28 @@ int sqlite3BtreeIsInStmt(Btree *pBt){ */ int sqlite3BtreeSync(Btree *pBt, const char *zMaster){ if( pBt->inTrans==TRANS_WRITE ){ - return sqlite3pager_sync(pBt->pPager, zMaster); +#ifndef SQLITE_OMIT_AUTOVACUUM + Pgno nTrunc = 0; + if( pBt->autoVacuum ){ + int rc = autoVacuumCommit(pBt, &nTrunc); + if( rc!=SQLITE_OK ) return rc; + } + return sqlite3pager_sync(pBt->pPager, zMaster, nTrunc); +#endif + return sqlite3pager_sync(pBt->pPager, zMaster, 0); } return SQLITE_OK; } + +#ifndef SQLITE_OMIT_GLOBALRECOVER +/* +** Reset the btree and underlying pager after a malloc() failure. Any +** transaction that was active when malloc() failed is rolled back. +*/ +int sqlite3BtreeReset(Btree *pBt){ + if( pBt->pCursor ) return SQLITE_BUSY; + pBt->inTrans = TRANS_NONE; + unlockBtreeIfUnused(pBt); + return sqlite3pager_reset(pBt->pPager); +} +#endif diff --git a/db/sqlite3/src/btree.h b/db/sqlite3/src/btree.h index 3f247b77ae8..19bb3d8f8d0 100644 --- a/db/sqlite3/src/btree.h +++ b/db/sqlite3/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.58 2004/07/23 00:01:39 drh Exp $ +** @(#) $Id: btree.h,v 1.63 2005/03/21 04:04:03 danielk1977 Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -23,6 +23,14 @@ */ #define SQLITE_N_BTREE_META 10 +/* +** If defined as non-zero, auto-vacuum is enabled by default. Otherwise +** it must be turned on for each database using "PRAGMA auto_vacuum = 1". +*/ +#ifndef SQLITE_DEFAULT_AUTOVACUUM + #define SQLITE_DEFAULT_AUTOVACUUM 0 +#endif + /* ** Forward declarations of structure */ @@ -38,9 +46,13 @@ int sqlite3BtreeOpen( /* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the ** following values. +** +** NOTE: These values must match the corresponding PAGER_ values in +** pager.h. */ #define BTREE_OMIT_JOURNAL 1 /* Do not use journal. No argument */ -#define BTREE_MEMORY 2 /* In-memory DB. No argument */ +#define BTREE_NO_READLOCK 2 /* Omit readlocks on readonly files */ +#define BTREE_MEMORY 4 /* In-memory DB. No argument */ int sqlite3BtreeClose(Btree*); int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*); @@ -49,6 +61,8 @@ int sqlite3BtreeSetSafetyLevel(Btree*,int); int sqlite3BtreeSetPageSize(Btree*,int,int); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeGetReserve(Btree*); +int sqlite3BtreeSetAutoVacuum(Btree *, int); +int sqlite3BtreeGetAutoVacuum(Btree *); int sqlite3BtreeBeginTrans(Btree*,int); int sqlite3BtreeCommit(Btree*); int sqlite3BtreeRollback(Btree*); @@ -59,6 +73,7 @@ int sqlite3BtreeCreateTable(Btree*, int*, int flags); int sqlite3BtreeIsInTrans(Btree*); int sqlite3BtreeIsInStmt(Btree*); int sqlite3BtreeSync(Btree*, const char *zMaster); +int sqlite3BtreeReset(Btree *); const char *sqlite3BtreeGetFilename(Btree *); const char *sqlite3BtreeGetDirname(Btree *); @@ -72,7 +87,7 @@ int sqlite3BtreeCopyFile(Btree *, Btree *); #define BTREE_ZERODATA 2 /* Table has keys only - no data */ #define BTREE_LEAFDATA 4 /* Data stored in leaves only. Implies INTKEY */ -int sqlite3BtreeDropTable(Btree*, int); +int sqlite3BtreeDropTable(Btree*, int, int*); int sqlite3BtreeClearTable(Btree*, int); int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); @@ -117,8 +132,12 @@ struct Pager *sqlite3BtreePager(Btree*); #ifdef SQLITE_TEST int sqlite3BtreeCursorInfo(BtCursor*, int*, int); void sqlite3BtreeCursorList(Btree*); -int sqlite3BtreePageDump(Btree*, int, int recursive); #endif +#ifdef SQLITE_DEBUG +int sqlite3BtreePageDump(Btree*, int, int recursive); +#else +#define sqlite3BtreePageDump(X,Y,Z) SQLITE_OK +#endif #endif /* _BTREE_H_ */ diff --git a/db/sqlite3/src/build.c b/db/sqlite3/src/build.c index 7ae1868af44..c9339313f17 100644 --- a/db/sqlite3/src/build.c +++ b/db/sqlite3/src/build.c @@ -21,18 +21,15 @@ ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK -** PRAGMA ** -** $Id: build.c,v 1.257 2004/10/06 15:41:16 drh Exp $ +** $Id: build.c,v 1.316 2005/03/21 03:53:38 danielk1977 Exp $ */ #include "sqliteInt.h" #include /* ** This routine is called when a new SQL statement is beginning to -** be parsed. Check to see if the schema for the database needs -** to be read from the SQLITE_MASTER and SQLITE_TEMP_MASTER tables. -** If it does, then read it. +** be parsed. Initialize the pParse structure as needed. */ void sqlite3BeginParse(Parse *pParse, int explainFlag){ pParse->explain = explainFlag; @@ -54,6 +51,13 @@ void sqlite3FinishCoding(Parse *pParse){ Vdbe *v; if( sqlite3_malloc_failed ) return; + if( pParse->nested ) return; + if( !pParse->pVdbe ){ + if( pParse->rc==SQLITE_OK && pParse->nErr ){ + pParse->rc = SQLITE_ERROR; + } + return; + } /* Begin by generating some termination code at the end of the ** vdbe program @@ -85,7 +89,7 @@ void sqlite3FinishCoding(Parse *pParse){ ** statement as its P3 argument. This does not change the functionality ** of the program. ** - ** This is used to implement sqlite3_trace() functionality. + ** This is used to implement sqlite3_trace(). */ sqlite3VdbeOp3(v, OP_Noop, 0, 0, pParse->zSql, pParse->zTail-pParse->zSql); } @@ -97,8 +101,8 @@ void sqlite3FinishCoding(Parse *pParse){ FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem+3, - pParse->nTab+3, pParse->explain); - pParse->rc = pParse->nErr ? SQLITE_ERROR : SQLITE_DONE; + pParse->nTab+3, pParse->nMaxDepth+1, pParse->explain); + pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else if( pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; @@ -106,12 +110,47 @@ void sqlite3FinishCoding(Parse *pParse){ pParse->nTab = 0; pParse->nMem = 0; pParse->nSet = 0; - pParse->nAgg = 0; pParse->nVar = 0; pParse->cookieMask = 0; pParse->cookieGoto = 0; } +/* +** Run the parser and code generator recursively in order to generate +** code for the SQL statement given onto the end of the pParse context +** currently under construction. When the parser is run recursively +** this way, the final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** Not everything is nestable. This facility is designed to permit +** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use +** care if you decide to try to use this routine for some other purposes. +*/ +void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ + va_list ap; + char *zSql; + int rc; +# define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) + char saveBuf[SAVE_SZ]; + + if( pParse->nErr ) return; + assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ + va_start(ap, zFormat); + zSql = sqlite3VMPrintf(zFormat, ap); + va_end(ap); + if( zSql==0 ){ + return; /* A malloc must have failed */ + } + pParse->nested++; + memcpy(saveBuf, &pParse->nVar, SAVE_SZ); + memset(&pParse->nVar, 0, SAVE_SZ); + rc = sqlite3RunParser(pParse, zSql, 0); + sqliteFree(zSql); + memcpy(&pParse->nVar, saveBuf, SAVE_SZ); + pParse->nested--; +} + /* ** Locate the in-memory structure that describes a particular database ** table given the name of that table and (optionally) the name of the @@ -279,8 +318,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ sqlite3HashClear(&pDb->aFKey); sqlite3HashClear(&pDb->idxHash); for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - Trigger *pTrigger = sqliteHashData(pElem); - sqlite3DeleteTrigger(pTrigger); + sqlite3DeleteTrigger((Trigger*)sqliteHashData(pElem)); } sqlite3HashClear(&temp2); sqlite3HashInit(&pDb->tblHash, SQLITE_HASH_STRING, 0); @@ -289,6 +327,7 @@ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ sqlite3DeleteTable(db, pTab); } sqlite3HashClear(&temp1); + pDb->pSeqTab = 0; DbClearProperty(db, i, DB_SchemaLoaded); if( iDb>0 ) return; } @@ -356,7 +395,7 @@ static void sqliteResetColumnNames(Table *pTable){ assert( pTable!=0 ); for(i=0, pCol=pTable->aCol; inCol; i++, pCol++){ sqliteFree(pCol->zName); - sqliteFree(pCol->zDflt); + sqlite3ExprDelete(pCol->pDflt); sqliteFree(pCol->zType); } sqliteFree(pTable->aCol); @@ -393,6 +432,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ sqliteDeleteIndex(db, pIndex); } +#ifndef SQLITE_OMIT_FOREIGN_KEY /* Delete all foreign keys associated with this table. The keys ** should have already been unlinked from the db->aFKey hash table */ @@ -403,6 +443,7 @@ void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey ); sqliteFree(pFKey); } +#endif /* Delete the Table structure itself. */ @@ -428,6 +469,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ pDb = &db->aDb[iDb]; p = sqlite3HashInsert(&pDb->tblHash, zTabName, strlen(zTabName)+1, 0); if( p ){ +#ifndef SQLITE_OMIT_FOREIGN_KEY for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){ int nTo = strlen(pF1->zTo) + 1; pF2 = sqlite3HashFind(&pDb->aFKey, pF1->zTo, nTo); @@ -440,6 +482,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ } } } +#endif sqlite3DeleteTable(db, p); } db->flags |= SQLITE_InternChanges; @@ -482,16 +525,23 @@ void sqlite3OpenMasterTable(Vdbe *v, int iDb){ ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ -int findDb(sqlite3 *db, Token *pName){ - int i; - Db *pDb; - for(pDb=db->aDb, i=0; inDb; i++, pDb++){ - if( pName->n==strlen(pDb->zName) && - 0==sqlite3StrNICmp(pDb->zName, pName->z, pName->n) ){ - return i; +static int findDb(sqlite3 *db, Token *pName){ + int i = -1; /* Database number */ + int n; /* Number of characters in the name */ + Db *pDb; /* A database whose name space is being searched */ + char *zName; /* Name we are searching for */ + + zName = sqlite3NameFromToken(pName); + if( zName ){ + n = strlen(zName); + for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ + if( n==strlen(pDb->zName) && 0==sqlite3StrICmp(pDb->zName, zName) ){ + break; + } } + sqliteFree(zName); } - return -1; + return i; } /* The table or view or trigger name is passed to this routine via tokens @@ -544,7 +594,8 @@ int sqlite3TwoPartName( ** is reserved for internal use. */ int sqlite3CheckObjectName(Parse *pParse, const char *zName){ - if( !pParse->db->init.busy && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ + if( !pParse->db->init.busy && pParse->nested==0 + && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } @@ -578,7 +629,7 @@ void sqlite3StartTable( ){ Table *pTable; Index *pIdx; - char *zName; + char *zName = 0; /* The name of the new table */ sqlite3 *db = pParse->db; Vdbe *v; int iDb; /* Database number to create the table in */ @@ -606,7 +657,6 @@ void sqlite3StartTable( if( isTemp && iDb>1 ){ /* If creating a temp table, the name may not be qualified */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); - pParse->nErr++; return; } if( isTemp ) iDb = 1; @@ -615,8 +665,7 @@ void sqlite3StartTable( zName = sqlite3NameFromToken(pName); if( zName==0 ) return; if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ - sqliteFree(zName); - return; + goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; #ifndef SQLITE_OMIT_AUTHORIZATION @@ -625,8 +674,7 @@ void sqlite3StartTable( int code; char *zDb = db->aDb[iDb].zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ - sqliteFree(zName); - return; + goto begin_table_error; } if( isView ){ if( isTemp ){ @@ -642,8 +690,7 @@ void sqlite3StartTable( } } if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ - sqliteFree(zName); - return; + goto begin_table_error; } } #endif @@ -652,25 +699,24 @@ void sqlite3StartTable( ** index or table name in the same database. Issue an error message if ** it does. */ - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto begin_table_error; + } pTable = sqlite3FindTable(db, zName, db->aDb[iDb].zName); if( pTable ){ sqlite3ErrorMsg(pParse, "table %T already exists", pName); - sqliteFree(zName); - return; + goto begin_table_error; } if( (pIdx = sqlite3FindIndex(db, zName, 0))!=0 && ( iDb==0 || !db->init.busy) ){ sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); - sqliteFree(zName); - return; + goto begin_table_error; } pTable = sqliteMalloc( sizeof(Table) ); if( pTable==0 ){ pParse->rc = SQLITE_NOMEM; pParse->nErr++; - sqliteFree(zName); - return; + goto begin_table_error; } pTable->zName = zName; pTable->nCol = 0; @@ -681,6 +727,16 @@ void sqlite3StartTable( if( pParse->pNewTable ) sqlite3DeleteTable(db, pParse->pNewTable); pParse->pNewTable = pTable; + /* If this is the magic sqlite_sequence table used by autoincrement, + ** then record a pointer to this table in the main database structure + ** so that INSERT can find the table easily. + */ +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( strcmp(zName, "sqlite_sequence")==0 ){ + db->aDb[iDb].pSeqTab = pTable; + } +#endif + /* Begin generating the code that will insert the table record into ** the SQLITE_MASTER table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any @@ -690,24 +746,68 @@ void sqlite3StartTable( ** now. */ if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ + int lbl; sqlite3BeginWriteOperation(pParse, 0, iDb); - /* Every time a new table is created the file-format - ** and encoding meta-values are set in the database, in - ** case this is the first table created. + + /* If the file format and encoding in the database have not been set, + ** set them now. */ + sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1); /* file_format */ + lbl = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp(v, OP_If, 0, lbl); sqlite3VdbeAddOp(v, OP_Integer, db->file_format, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1); sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4); + sqlite3VdbeResolveLabel(v, lbl); + /* This just creates a place-holder record in the sqlite_master table. + ** The record created does not contain anything yet. It will be replaced + ** by the real entry in code generated at sqlite3EndTable(). + ** + ** The rowid for the new entry is left on the top of the stack. + ** The rowid value is needed by the code that sqlite3EndTable will + ** generate. + */ +#ifndef SQLITE_OMIT_VIEW + if( isView ){ + sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + }else +#endif + { + sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0); + } sqlite3OpenMasterTable(v, iDb); sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); sqlite3VdbeAddOp(v, OP_String8, 0, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + sqlite3VdbeAddOp(v, OP_Close, 0, 0); + sqlite3VdbeAddOp(v, OP_Pull, 1, 0); } + + /* Normal (non-error) return. */ + return; + + /* If an error occurs, we jump here */ +begin_table_error: + sqliteFree(zName); + return; } +/* +** This macro is used to compare two strings in a case-insensitive manner. +** It is slightly faster than calling sqlite3StrICmp() directly, but +** produces larger code. +** +** WARNING: This macro is not compatible with the strcmp() family. It +** returns true if the two strings are equal, otherwise false. +*/ +#define STRICMP(x, y) (\ +sqlite3UpperToLower[*(unsigned char *)(x)]== \ +sqlite3UpperToLower[*(unsigned char *)(y)] \ +&& sqlite3StrICmp((x)+1,(y)+1)==0 ) + /* ** Add a new column to the table currently being constructed. ** @@ -725,7 +825,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){ z = sqlite3NameFromToken(pName); if( z==0 ) return; for(i=0; inCol; i++){ - if( sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ + if( STRICMP(z, p->aCol[i].zName) ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqliteFree(z); return; @@ -734,7 +834,10 @@ void sqlite3AddColumn(Parse *pParse, Token *pName){ if( (p->nCol & 0x7)==0 ){ Column *aNew; aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0])); - if( aNew==0 ) return; + if( aNew==0 ){ + sqliteFree(z); + return; + } p->aCol = aNew; } pCol = &p->aCol[p->nCol]; @@ -764,6 +867,55 @@ void sqlite3AddNotNull(Parse *pParse, int onError){ if( i>=0 ) p->aCol[i].notNull = onError; } +/* +** Scan the column type name zType (length nType) and return the +** associated affinity type. +** +** This routine does a case-independent search of zType for the +** substrings in the following table. If one of the substrings is +** found, the corresponding affinity is returned. If zType contains +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', +** SQLITE_AFF_INTEGER is returned. +** +** Substring | Affinity +** -------------------------------- +** 'INT' | SQLITE_AFF_INTEGER +** 'CHAR' | SQLITE_AFF_TEXT +** 'CLOB' | SQLITE_AFF_TEXT +** 'TEXT' | SQLITE_AFF_TEXT +** 'BLOB' | SQLITE_AFF_NONE +** +** If none of the substrings in the above table are found, +** SQLITE_AFF_NUMERIC is returned. +*/ +static char sqlite3AffinityType(const char *zType, int nType){ + u32 h = 0; + char aff = SQLITE_AFF_NUMERIC; + const unsigned char *zIn = zType; + const unsigned char *zEnd = (zIn+nType); + + while( zIn!=zEnd ){ + h = (h<<8) + sqlite3UpperToLower[*zIn]; + zIn++; + if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){ /* CLOB */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){ /* TEXT */ + aff = SQLITE_AFF_TEXT; + }else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b') /* BLOB */ + && aff==SQLITE_AFF_NUMERIC ){ + aff = SQLITE_AFF_NONE; + }else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){ /* INT */ + aff = SQLITE_AFF_INTEGER; + break; + } + } + + return aff; +} + /* ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. The pFirst token is the first @@ -777,19 +929,21 @@ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){ Table *p; int i, j; int n; - char *z, **pz; + char *z; + const unsigned char *zIn; + Column *pCol; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; if( i<0 ) return; pCol = &p->aCol[i]; - pz = &pCol->zType; - n = pLast->n + (pLast->z - pFirst->z); + zIn = pFirst->z; + n = pLast->n + (pLast->z - zIn); assert( pCol->zType==0 ); - z = pCol->zType = sqlite3MPrintf("%.*s", n, pFirst->z); + z = pCol->zType = sqliteMallocRaw(n+1); if( z==0 ) return; - for(i=j=0; z[i]; i++){ - int c = z[i]; + for(i=j=0; ipNewTable)==0 ) return; - i = p->nCol-1; - if( i<0 ) return; - assert( p->aCol[i].zDflt==0 ); - z = p->aCol[i].zDflt = sqlite3MPrintf("%s%T", minusFlag ? "-" : "", pVal); - sqlite3Dequote(z); + pCol = &(p->aCol[p->nCol-1]); + if( !sqlite3ExprIsConstant(pExpr) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + pCol->zName); + }else{ + sqlite3ExprDelete(pCol->pDflt); + pCol->pDflt = sqlite3ExprDup(pExpr); + } + sqlite3ExprDelete(pExpr); } /* @@ -827,9 +986,7 @@ void sqlite3AddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){ ** error. ** ** If the PRIMARY KEY is on a single column whose datatype is INTEGER, -** then we will try to use that column as the row id. (Exception: -** For backwards compatibility with older databases, do not do this -** if the file format version number is less than 1.) Set the Table.iPKey +** then we will try to use that column as the rowid. Set the Table.iPKey ** field of the table under construction to be the index of the ** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is ** no INTEGER PRIMARY KEY. @@ -837,7 +994,12 @@ void sqlite3AddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){ ** If the key is not an INTEGER PRIMARY KEY, then create a unique ** index for the key. No index is created for INTEGER PRIMARY KEYs. */ -void sqlite3AddPrimaryKey(Parse *pParse, ExprList *pList, int onError){ +void sqlite3AddPrimaryKey( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* List of field names to be indexed */ + int onError, /* What to do with a uniqueness conflict */ + int autoInc /* True if the AUTOINCREMENT keyword is present */ +){ Table *pTab = pParse->pNewTable; char *zType = 0; int iCol = -1, i; @@ -868,6 +1030,12 @@ void sqlite3AddPrimaryKey(Parse *pParse, ExprList *pList, int onError){ if( zType && sqlite3StrICmp(zType, "INTEGER")==0 ){ pTab->iPKey = iCol; pTab->keyConf = onError; + pTab->autoInc = autoInc; + }else if( autoInc ){ +#ifndef SQLITE_OMIT_AUTOINCREMENT + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + "INTEGER PRIMARY KEY"); +#endif }else{ sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0); pList = 0; @@ -930,6 +1098,7 @@ static CollSeq * findCollSeqEntry( if( 0==pColl && create ){ pColl = sqliteMalloc( 3*sizeof(*pColl) + nName + 1 ); if( pColl ){ + CollSeq *pDel = 0; pColl[0].zName = (char*)&pColl[3]; pColl[0].enc = SQLITE_UTF8; pColl[1].zName = (char*)&pColl[3]; @@ -938,7 +1107,14 @@ static CollSeq * findCollSeqEntry( pColl[2].enc = SQLITE_UTF16BE; memcpy(pColl[0].zName, zName, nName); pColl[0].zName[nName] = 0; - sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl); + + /* If a malloc() failure occured in sqlite3HashInsert(), it will + ** return the pColl pointer to be deleted (because it wasn't added + ** to the hash table). + */ + assert( !pDel || (sqlite3_malloc_failed && pDel==pColl) ); + sqliteFree(pDel); } } return pColl; @@ -980,6 +1156,7 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ db->xCollNeeded(db->pCollNeededArg, db, (int)db->enc, zExternal); sqliteFree(zExternal); } +#ifndef SQLITE_OMIT_UTF16 if( db->xCollNeeded16 ){ char const *zExternal; sqlite3_value *pTmp = sqlite3GetTransientValue(db); @@ -988,6 +1165,7 @@ static void callCollNeeded(sqlite3 *db, const char *zName, int nName){ if( !zExternal ) return; db->xCollNeeded16(db->pCollNeededArg, db, (int)db->enc, zExternal); } +#endif } /* @@ -1105,44 +1283,6 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName, int nName){ } - -/* -** Scan the column type name zType (length nType) and return the -** associated affinity type. -*/ -char sqlite3AffinityType(const char *zType, int nType){ - int n, i; - static const struct { - const char *zSub; /* Keywords substring to search for */ - char nSub; /* length of zSub */ - char affinity; /* Affinity to return if it matches */ - } substrings[] = { - {"INT", 3, SQLITE_AFF_INTEGER}, - {"CHAR", 4, SQLITE_AFF_TEXT}, - {"CLOB", 4, SQLITE_AFF_TEXT}, - {"TEXT", 4, SQLITE_AFF_TEXT}, - {"BLOB", 4, SQLITE_AFF_NONE}, - }; - - if( nType==0 ){ - return SQLITE_AFF_NONE; - } - for(i=0; iinit.busy==1. When db->init.busy==1 ** it means we are reading the sqlite_master table because we just ** connected to the database or because the sqlite_master table has -** recently changes, so the entry for this table already exists in +** recently changed, so the entry for this table already exists in ** the sqlite_master table. We do not want to create it again. ** ** If the pSelect argument is not NULL, it means that this routine @@ -1273,7 +1413,12 @@ static char *createTableStmt(Table *p){ ** "CREATE TABLE ... AS SELECT ..." statement. The column names of ** the new table will match the result set of the SELECT. */ -void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ +void sqlite3EndTable( + Parse *pParse, /* Parse context */ + Token *pCons, /* The ',' token after the last column defn. */ + Token *pEnd, /* The final ')' token in the CREATE TABLE */ + Select *pSelect /* Select from a "CREATE ... AS SELECT" */ +){ Table *p; sqlite3 *db = pParse->db; @@ -1303,20 +1448,33 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ if( !db->init.busy ){ int n; Vdbe *v; + char *zType; /* "view" or "table" */ + char *zType2; /* "VIEW" or "TABLE" */ + char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ v = sqlite3GetVdbe(pParse); if( v==0 ) return; + sqlite3VdbeAddOp(v, OP_Close, 0, 0); + + /* Create the rootpage for the new table and push it onto the stack. + ** A view has no rootpage, so just push a zero onto the stack for + ** views. Initialize zType at the same time. + */ if( p->pSelect==0 ){ /* A regular table */ - sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); + /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */ + zType = "table"; + zType2 = "TABLE"; +#ifndef SQLITE_OMIT_VIEW }else{ /* A view */ - sqlite3VdbeAddOp(v, OP_Integer, 0, 0); + /* sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */ + zType = "view"; + zType2 = "VIEW"; +#endif } - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT ** statement to populate the new table. The root-page number for the ** new table is on the top of the vdbe stack. @@ -1344,40 +1502,55 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ sqlite3DeleteTable(0, pSelTab); } } - - sqlite3OpenMasterTable(v, p->iDb); - - sqlite3VdbeOp3(v, OP_String8, 0, 0, p->pSelect==0?"table":"view",P3_STATIC); - sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, p->zName, 0); - sqlite3VdbeAddOp(v, OP_Pull, 3, 0); + /* Compute the complete text of the CREATE statement */ if( pSelect ){ - char *z = createTableStmt(p); - n = z ? strlen(z) : 0; - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeChangeP3(v, -1, z, n); - sqliteFree(z); + zStmt = createTableStmt(p); }else{ - if( p->pSelect ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE VIEW ", P3_STATIC); - }else{ - sqlite3VdbeOp3(v, OP_String8, 0, 0, "CREATE TABLE ", P3_STATIC); - } - assert( pEnd!=0 ); n = Addr(pEnd->z) - Addr(pParse->sNameToken.z) + 1; - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - sqlite3VdbeChangeP3(v, -1, pParse->sNameToken.z, n); - sqlite3VdbeAddOp(v, OP_Concat, 0, 0); + zStmt = sqlite3MPrintf("CREATE %s %.*s", zType2, n, pParse->sNameToken.z); } - sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); - sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + + /* A slot for the record has already been allocated in the + ** SQLITE_MASTER table. We just need to update that slot with all + ** the information we've collected. The rowid for the preallocated + ** slot is the 2nd item on the stack. The top of the stack is the + ** root page for the new table (or a 0 if this is a view). + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s " + "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#0, sql=%Q " + "WHERE rowid=#1", + db->aDb[p->iDb].zName, SCHEMA_TABLE(p->iDb), + zType, + p->zName, + p->zName, + zStmt + ); + sqliteFree(zStmt); sqlite3ChangeCookie(db, v, p->iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); + +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Check to see if we need to create an sqlite_sequence table for + ** keeping track of autoincrement keys. + */ + if( p->autoInc ){ + Db *pDb = &db->aDb[p->iDb]; + if( pDb->pSeqTab==0 ){ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.sqlite_sequence(name,seq)", + pDb->zName + ); + } + } +#endif + + /* Reparse everything to update our internal data structures */ sqlite3VdbeOp3(v, OP_ParseSchema, p->iDb, 0, sqlite3MPrintf("tbl_name='%q'",p->zName), P3_DYNAMIC); } + /* Add the table to the in-memory representation of the database. */ if( db->init.busy && pParse->nErr==0 ){ @@ -1389,17 +1562,28 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ return; } +#ifndef SQLITE_OMIT_FOREIGN_KEY for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ int nTo = strlen(pFKey->zTo) + 1; pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo); sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey); } +#endif pParse->pNewTable = 0; db->nTable++; db->flags |= SQLITE_InternChanges; + +#ifndef SQLITE_OMIT_ALTERTABLE + if( !p->pSelect ){ + assert( !pSelect && pCons && pEnd ); + if( pCons->z==0 ) pCons = pEnd; + p->addColOffset = 13 + (pCons->z - pParse->sNameToken.z); + } +#endif } } +#ifndef SQLITE_OMIT_VIEW /* ** The parser calls this routine in order to create a new VIEW */ @@ -1458,20 +1642,22 @@ void sqlite3CreateView( sEnd.n = 1; /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */ - sqlite3EndTable(pParse, &sEnd, 0); + sqlite3EndTable(pParse, 0, &sEnd, 0); return; } +#endif /* SQLITE_OMIT_VIEW */ +#ifndef SQLITE_OMIT_VIEW /* ** The Table structure pTable is really a VIEW. Fill in the names of ** the columns of the view in the pTable structure. Return the number ** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ - ExprList *pEList; - Select *pSel; - Table *pSelTab; - int nErr = 0; + Table *pSelTab; /* A fake table from which we get the result set */ + Select *pSel; /* Copy of the SELECT that implements the view */ + int nErr = 0; /* Number of errors encountered */ + int n; /* Temporarily holds the number of cursors assigned */ assert( pTable ); @@ -1496,23 +1682,19 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ } /* If we get this far, it means we need to compute the table names. + ** Note that the call to sqlite3ResultSetOfSelect() will expand any + ** "*" elements in the results set of the view and will assign cursors + ** to the elements of the FROM clause. But we do not want these changes + ** to be permanent. So the computation is done on a copy of the SELECT + ** statement that defines the view. */ - assert( pTable->pSelect ); /* If nCol==0, then pTable must be a VIEW */ - pSel = pTable->pSelect; - - /* Note that the call to sqlite3ResultSetOfSelect() will expand any - ** "*" elements in this list. But we will need to restore the list - ** back to its original configuration afterwards, so we save a copy of - ** the original in pEList. - */ - pEList = pSel->pEList; - pSel->pEList = sqlite3ExprListDup(pEList); - if( pSel->pEList==0 ){ - pSel->pEList = pEList; - return 1; /* Malloc failed */ - } + assert( pTable->pSelect ); + pSel = sqlite3SelectDup(pTable->pSelect); + n = pParse->nTab; + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSel); + pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; @@ -1525,12 +1707,12 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->nCol = 0; nErr++; } - sqlite3SelectUnbind(pSel); - sqlite3ExprListDelete(pSel->pEList); - pSel->pEList = pEList; + sqlite3SelectDelete(pSel); return nErr; } +#endif /* SQLITE_OMIT_VIEW */ +#ifndef SQLITE_OMIT_VIEW /* ** Clear the column names from every VIEW in database idx. */ @@ -1545,6 +1727,115 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ } DbClearProperty(db, idx, DB_UnresetViews); } +#else +# define sqliteViewResetAll(A,B) +#endif /* SQLITE_OMIT_VIEW */ + +/* +** This function is called by the VDBE to adjust the internal schema +** used by SQLite when the btree layer moves a table root page. The +** root-page of a table or index in database iDb has changed from iFrom +** to iTo. +*/ +#ifndef SQLITE_OMIT_AUTOVACUUM +void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){ + HashElem *pElem; + + for(pElem=sqliteHashFirst(&pDb->tblHash); pElem; pElem=sqliteHashNext(pElem)){ + Table *pTab = sqliteHashData(pElem); + if( pTab->tnum==iFrom ){ + pTab->tnum = iTo; + return; + } + } + for(pElem=sqliteHashFirst(&pDb->idxHash); pElem; pElem=sqliteHashNext(pElem)){ + Index *pIdx = sqliteHashData(pElem); + if( pIdx->tnum==iFrom ){ + pIdx->tnum = iTo; + return; + } + } + assert(0); +} +#endif + +/* +** Write code to erase the table with root-page iTable from database iDb. +** Also write code to modify the sqlite_master table and internal schema +** if a root-page of another table is moved by the btree-layer whilst +** erasing iTable (this can happen with an auto-vacuum database). +*/ +static void destroyRootPage(Parse *pParse, int iTable, int iDb){ + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3VdbeAddOp(v, OP_Destroy, iTable, iDb); +#ifndef SQLITE_OMIT_AUTOVACUUM + /* OP_Destroy pushes an integer onto the stack. If this integer + ** is non-zero, then it is the root page number of a table moved to + ** location iTable. The following code modifies the sqlite_master table to + ** reflect this. + ** + ** The "#0" in the SQL is a special constant that means whatever value + ** is on the top of the stack. See sqlite3RegisterExpr(). + */ + sqlite3NestedParse(pParse, + "UPDATE %Q.%s SET rootpage=%d WHERE #0 AND rootpage=#0", + pParse->db->aDb[iDb].zName, SCHEMA_TABLE(iDb), iTable); +#endif +} + +/* +** Write VDBE code to erase table pTab and all associated indices on disk. +** Code to update the sqlite_master tables and internal schema definitions +** in case a root-page belonging to another table is moved by the btree layer +** is also added (this can happen with an auto-vacuum database). +*/ +static void destroyTable(Parse *pParse, Table *pTab){ +#ifdef SQLITE_OMIT_AUTOVACUUM + Index *pIdx; + destroyRootPage(pParse, pTab->tnum, pTab->iDb); + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + destroyRootPage(pParse, pIdx->tnum, pIdx->iDb); + } +#else + /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM + ** is not defined), then it is important to call OP_Destroy on the + ** table and index root-pages in order, starting with the numerically + ** largest root-page number. This guarantees that none of the root-pages + ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the + ** following were coded: + ** + ** OP_Destroy 4 0 + ** ... + ** OP_Destroy 5 0 + ** + ** and root page 5 happened to be the largest root-page number in the + ** database, then root page 5 would be moved to page 4 by the + ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit + ** a free-list page. + */ + int iTab = pTab->tnum; + int iDestroyed = 0; + + while( 1 ){ + Index *pIdx; + int iLargest = 0; + + if( iDestroyed==0 || iTabpIndex; pIdx; pIdx=pIdx->pNext){ + int iIdx = pIdx->tnum; + assert( pIdx->iDb==pTab->iDb ); + if( (iDestroyed==0 || (iIdxiLargest ){ + iLargest = iIdx; + } + } + if( iLargest==0 ) return; + destroyRootPage(pParse, iLargest, pTab->iDb); + iDestroyed = iLargest; + } +#endif +} /* ** This routine is called to do the work of a DROP TABLE statement. @@ -1553,7 +1844,6 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ Table *pTab; Vdbe *v; - int base; sqlite3 *db = pParse->db; int iDb; @@ -1593,11 +1883,15 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ } } #endif - if( pTab->readOnly ){ + if( pTab->readOnly || pTab==db->aDb[iDb].pSeqTab ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); - pParse->nErr++; goto exit_drop_table; } + +#ifndef SQLITE_OMIT_VIEW + /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used + ** on a table. + */ if( isView && pTab->pSelect==0 ){ sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); goto exit_drop_table; @@ -1606,30 +1900,17 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); goto exit_drop_table; } +#endif /* Generate code to remove the table from the master table ** on disk. */ v = sqlite3GetVdbe(pParse); if( v ){ - static const VdbeOpList dropTable[] = { - { OP_Rewind, 0, ADDR(13), 0}, - { OP_String8, 0, 0, 0}, /* 1 */ - { OP_MemStore, 1, 1, 0}, - { OP_MemLoad, 1, 0, 0}, /* 3 */ - { OP_Column, 0, 2, 0}, /* sqlite_master.tbl_name */ - { OP_Ne, 0, ADDR(12), 0}, - { OP_String8, 0, 0, "trigger"}, - { OP_Column, 0, 2, 0}, /* sqlite_master.type */ - { OP_Eq, 0, ADDR(12), 0}, - { OP_Delete, 0, 0, 0}, - { OP_Rewind, 0, ADDR(13), 0}, - { OP_Goto, 0, ADDR(3), 0}, - { OP_Next, 0, ADDR(3), 0}, /* 12 */ - }; - Index *pIdx; Trigger *pTrigger; - sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); + int iDb = pTab->iDb; + Db *pDb = &db->aDb[iDb]; + sqlite3BeginWriteOperation(pParse, 0, iDb); /* Drop all triggers associated with the table being dropped. Code ** is generated to remove entries from sqlite_master and/or @@ -1637,11 +1918,25 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ */ pTrigger = pTab->pTrigger; while( pTrigger ){ - assert( pTrigger->iDb==pTab->iDb || pTrigger->iDb==1 ); + assert( pTrigger->iDb==iDb || pTrigger->iDb==1 ); sqlite3DropTriggerPtr(pParse, pTrigger, 1); pTrigger = pTrigger->pNext; } +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Remove any entries of the sqlite_sequence table associated with + ** the table being dropped. This is done before the table is dropped + ** at the btree level, in case the sqlite_sequence table needs to + ** move as a result of the drop (can happen in auto-vacuum mode). + */ + if( pTab->autoInc ){ + sqlite3NestedParse(pParse, + "DELETE FROM %s.sqlite_sequence WHERE name=%Q", + pDb->zName, pTab->zName + ); + } +#endif + /* Drop all SQLITE_MASTER table and index entries that refer to the ** table. The program name loops through the master table and deletes ** every row that refers to a table of the same name as the one being @@ -1649,18 +1944,18 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView){ ** created in the temp database that refers to a table in another ** database. */ - sqlite3OpenMasterTable(v, pTab->iDb); - base = sqlite3VdbeAddOpList(v, ArraySize(dropTable), dropTable); - sqlite3VdbeChangeP3(v, base+1, pTab->zName, 0); - sqlite3ChangeCookie(db, v, pTab->iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", + pDb->zName, SCHEMA_TABLE(iDb), pTab->zName); if( !isView ){ - sqlite3VdbeAddOp(v, OP_Destroy, pTab->tnum, pTab->iDb); - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - sqlite3VdbeAddOp(v, OP_Destroy, pIdx->tnum, pIdx->iDb); - } + destroyTable(pParse, pTab); } - sqlite3VdbeOp3(v, OP_DropTable, pTab->iDb, 0, pTab->zName, 0); + + /* Remove the table entry from SQLite's internal schema and modify + ** the schema cookie. + */ + sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0); + sqlite3ChangeCookie(db, v, iDb); } sqliteViewResetAll(db, iDb); @@ -1693,12 +1988,13 @@ void sqlite3CreateForeignKey( ExprList *pToCol, /* Columns in the other table */ int flags /* Conflict resolution algorithms. */ ){ +#ifndef SQLITE_OMIT_FOREIGN_KEY + FKey *pFKey = 0; Table *p = pParse->pNewTable; int nByte; int i; int nCol; char *z; - FKey *pFKey = 0; assert( pTo!=0 ); if( p==0 || pParse->nErr ) goto fk_end; @@ -1779,6 +2075,7 @@ void sqlite3CreateForeignKey( fk_end: sqliteFree(pFKey); +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ sqlite3ExprListDelete(pFromCol); sqlite3ExprListDelete(pToCol); } @@ -1791,15 +2088,80 @@ fk_end: ** accordingly. */ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +#ifndef SQLITE_OMIT_FOREIGN_KEY Table *pTab; FKey *pFKey; if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; pFKey->isDeferred = isDeferred; +#endif } /* -** Create a new index for an SQL table. pIndex is the name of the index -** and pTable is the name of the table that is to be indexed. Both will +** Generate code that will erase and refill index *pIdx. This is +** used to initialize a newly created index or to recompute the +** content of an index in response to a REINDEX command. +** +** if memRootPage is not negative, it means that the index is newly +** created. The memory cell specified by memRootPage contains the +** root page number of the index. If memRootPage is negative, then +** the index already exists and must be cleared before being refilled and +** the root page number of the index is taken from pIndex->tnum. +*/ +static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ + Table *pTab = pIndex->pTable; /* The table that is indexed */ + int iTab = pParse->nTab; /* Btree cursor used for pTab */ + int iIdx = pParse->nTab+1; /* Btree cursor used for pIndex */ + int addr1; /* Address of top of loop */ + int tnum; /* Root page of index */ + Vdbe *v; /* Generate code into this virtual machine */ + int isUnique; /* True for a unique index */ + +#ifndef SQLITE_OMIT_AUTHORIZATION + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + pParse->db->aDb[pIndex->iDb].zName ) ){ + return; + } +#endif + + /* Ensure all the required collation sequences are available. This + ** routine will invoke the collation-needed callback if necessary (and + ** if one has been registered). + */ + if( sqlite3CheckIndexCollSeq(pParse, pIndex) ){ + return; + } + + v = sqlite3GetVdbe(pParse); + if( v==0 ) return; + if( memRootPage>=0 ){ + sqlite3VdbeAddOp(v, OP_MemLoad, memRootPage, 0); + tnum = 0; + }else{ + tnum = pIndex->tnum; + sqlite3VdbeAddOp(v, OP_Clear, tnum, pIndex->iDb); + } + sqlite3VdbeAddOp(v, OP_Integer, pIndex->iDb, 0); + sqlite3VdbeOp3(v, OP_OpenWrite, iIdx, tnum, + (char*)&pIndex->keyInfo, P3_KEYINFO); + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenRead, iTab, pTab->tnum); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iTab, pTab->nCol); + addr1 = sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0); + sqlite3GenerateIndexKey(v, pIndex, iTab); + isUnique = pIndex->onError!=OE_None; + sqlite3VdbeAddOp(v, OP_IdxPut, iIdx, isUnique); + if( isUnique ){ + sqlite3VdbeChangeP3(v, -1, "indexed columns are not unique", P3_STATIC); + } + sqlite3VdbeAddOp(v, OP_Next, iTab, addr1+1); + sqlite3VdbeChangeP2(v, addr1, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp(v, OP_Close, iTab, 0); + sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); +} + +/* +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is @@ -1810,16 +2172,16 @@ void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ ** to the table currently under construction. */ void sqlite3CreateIndex( - Parse *pParse, /* All information about this parse */ - Token *pName1, /* First part of index name. May be NULL */ - Token *pName2, /* Second part of index name. May be NULL */ - SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ + Parse *pParse, /* All information about this parse */ + Token *pName1, /* First part of index name. May be NULL */ + Token *pName2, /* Second part of index name. May be NULL */ + SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ ExprList *pList, /* A list of columns to be indexed */ - int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ - Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ - Token *pEnd /* The ")" that closes the CREATE INDEX statement */ + int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ + Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */ + Token *pEnd /* The ")" that closes the CREATE INDEX statement */ ){ - Table *pTab = 0; /* Table to be indexed */ + Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; int i, j; @@ -1874,10 +2236,12 @@ void sqlite3CreateIndex( sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } +#ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; } +#endif isTemp = pTab->iDb==1; /* @@ -1913,7 +2277,7 @@ void sqlite3CreateIndex( goto exit_create_index; } } - }else if( pName==0 ){ + }else{ char zBuf[30]; int n; Index *pLoop; @@ -1956,7 +2320,7 @@ void sqlite3CreateIndex( */ pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 + (sizeof(int) + sizeof(CollSeq*))*pList->nExpr ); - if( pIndex==0 ) goto exit_create_index; + if( sqlite3_malloc_failed ) goto exit_create_index; pIndex->aiColumn = (int*)&pIndex->keyInfo.aColl[pList->nExpr]; pIndex->zName = (char*)&pIndex->aiColumn[pList->nExpr]; strcpy(pIndex->zName, zName); @@ -2076,60 +2440,55 @@ void sqlite3CreateIndex( ** step can be skipped. */ else if( db->init.busy==0 ){ - int n; Vdbe *v; - int lbl1, lbl2; + char *zStmt; + int iMem = pParse->nMem++; v = sqlite3GetVdbe(pParse); if( v==0 ) goto exit_create_index; - if( pTblName!=0 ){ - sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3OpenMasterTable(v, iDb); - } - sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, "index", P3_STATIC); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pIndex->zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + + /* Create the rootpage for the index + */ + sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0); - if( pTblName ){ - sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3VdbeAddOp(v, OP_Integer, iDb, 0); - sqlite3VdbeOp3(v, OP_OpenWrite, 1, 0, - (char*)&pIndex->keyInfo, P3_KEYINFO); - } - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); + + /* Gather the complete text of the CREATE INDEX statement into + ** the zStmt variable + */ if( pStart && pEnd ){ - if( onError==OE_None ){ - sqlite3VdbeChangeP3(v, -1, "CREATE INDEX ", P3_STATIC); - }else{ - sqlite3VdbeChangeP3(v, -1, "CREATE UNIQUE INDEX ", P3_STATIC); - } - sqlite3VdbeAddOp(v, OP_String8, 0, 0); - n = Addr(pEnd->z) - Addr(pName->z) + 1; - sqlite3VdbeChangeP3(v, -1, pName->z, n); - sqlite3VdbeAddOp(v, OP_Concat, 0, 0); + /* A named index with an explicit CREATE INDEX statement */ + zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s", + onError==OE_None ? "" : " UNIQUE", + Addr(pEnd->z) - Addr(pName->z) + 1, + pName->z); + }else{ + /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ + /* zStmt = sqlite3MPrintf(""); */ + zStmt = 0; } - sqlite3VdbeOp3(v, OP_MakeRecord, 5, 0, "tttit", P3_STATIC); - sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0); + + /* Add an entry in sqlite_master for this index + */ + sqlite3NestedParse(pParse, + "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#0,%Q);", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pIndex->zName, + pTab->zName, + zStmt + ); + sqlite3VdbeAddOp(v, OP_Pop, 1, 0); + sqliteFree(zStmt); + + /* Fill the index with data and reparse the schema. Code an OP_Expire + ** to invalidate all pre-compiled statements. + */ if( pTblName ){ - sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); - sqlite3VdbeAddOp(v, OP_OpenRead, 2, pTab->tnum); - /* VdbeComment((v, "%s", pTab->zName)); */ - sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol); - lbl2 = sqlite3VdbeMakeLabel(v); - sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2); - lbl1 = sqlite3VdbeCurrentAddr(v); - sqlite3GenerateIndexKey(v, pIndex, 2); - sqlite3VdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None, - "indexed columns are not unique", P3_STATIC); - sqlite3VdbeAddOp(v, OP_Next, 2, lbl1); - sqlite3VdbeResolveLabel(v, lbl2); - sqlite3VdbeAddOp(v, OP_Close, 2, 0); - sqlite3VdbeAddOp(v, OP_Close, 1, 0); + sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(db, v, iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC); + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); } } @@ -2174,9 +2533,13 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ Vdbe *v; sqlite3 *db = pParse->db; - if( pParse->nErr || sqlite3_malloc_failed ) return; + if( pParse->nErr || sqlite3_malloc_failed ){ + goto exit_drop_index; + } assert( pName->nSrc==1 ); - if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) return; + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + goto exit_drop_index; + } pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); @@ -2207,27 +2570,15 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName){ /* Generate code to remove the index and from the master table */ v = sqlite3GetVdbe(pParse); if( v ){ - static const VdbeOpList dropIndex[] = { - { OP_Rewind, 0, ADDR(9), 0}, - { OP_String8, 0, 0, 0}, /* 1 */ - { OP_MemStore, 1, 1, 0}, - { OP_MemLoad, 1, 0, 0}, /* 3 */ - { OP_Column, 0, 1, 0}, - { OP_Eq, 0, ADDR(8), 0}, - { OP_Next, 0, ADDR(3), 0}, - { OP_Goto, 0, ADDR(9), 0}, - { OP_Delete, 0, 0, 0}, /* 8 */ - }; - int base; - - sqlite3BeginWriteOperation(pParse, 0, pIndex->iDb); - sqlite3OpenMasterTable(v, pIndex->iDb); - base = sqlite3VdbeAddOpList(v, ArraySize(dropIndex), dropIndex); - sqlite3VdbeChangeP3(v, base+1, pIndex->zName, 0); - sqlite3ChangeCookie(db, v, pIndex->iDb); - sqlite3VdbeAddOp(v, OP_Close, 0, 0); - sqlite3VdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb); - sqlite3VdbeOp3(v, OP_DropIndex, pIndex->iDb, 0, pIndex->zName, 0); + int iDb = pIndex->iDb; + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE name=%Q", + db->aDb[iDb].zName, SCHEMA_TABLE(iDb), + pIndex->zName + ); + sqlite3ChangeCookie(db, v, iDb); + destroyRootPage(pParse, pIndex->tnum, iDb); + sqlite3VdbeOp3(v, OP_DropIndex, iDb, 0, pIndex->zName, 0); } exit_drop_index: @@ -2327,9 +2678,12 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){ */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - for(i=0; inSrc; i++){ - if( pList->a[i].iCursor<0 ){ - pList->a[i].iCursor = pParse->nTab++; + struct SrcList_item *pItem; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pItem->iCursor>=0 ) break; + pItem->iCursor = pParse->nTab++; + if( pItem->pSelect ){ + sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); } } } @@ -2544,7 +2898,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ if( v==0 ) return; sqlite3CodeVerifySchema(pParse, iDb); pParse->writeMask |= 1<nested==0 ){ sqlite3VdbeAddOp(v, OP_Statement, iDb, 0); } if( iDb!=1 && pParse->db->aDb[1].pBt!=0 ){ @@ -2552,6 +2906,7 @@ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ } } +#ifndef SQLITE_OMIT_UTF16 /* ** Return the transient sqlite3_value object used for encoding conversions ** during SQL compilation. @@ -2562,3 +2917,121 @@ sqlite3_value *sqlite3GetTransientValue(sqlite3 *db){ } return db->pValue; } +#endif + +/* +** Check to see if pIndex uses the collating sequence pColl. Return +** true if it does and false if it does not. +*/ +#ifndef SQLITE_OMIT_REINDEX +static int collationMatch(CollSeq *pColl, Index *pIndex){ + int n = pIndex->keyInfo.nField; + CollSeq **pp = pIndex->keyInfo.aColl; + while( n-- ){ + if( *pp==pColl ) return 1; + pp++; + } + return 0; +} +#endif + +/* +** Recompute all indices of pTab that use the collating sequence pColl. +** If pColl==0 then recompute all indices of pTab. +*/ +#ifndef SQLITE_OMIT_REINDEX +void reindexTable(Parse *pParse, Table *pTab, CollSeq *pColl){ + Index *pIndex; /* An index associated with pTab */ + + for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ + if( pColl==0 || collationMatch(pColl,pIndex) ){ + sqlite3BeginWriteOperation(pParse, 0, pTab->iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + } + } +} +#endif + +/* +** Recompute all indices of all tables in all databases where the +** indices use the collating sequence pColl. If pColl==0 then recompute +** all indices everywhere. +*/ +#ifndef SQLITE_OMIT_REINDEX +void reindexDatabases(Parse *pParse, CollSeq *pColl){ + Db *pDb; /* A single database */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + HashElem *k; /* For looping over tables in pDb */ + Table *pTab; /* A table in the database */ + + for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ + if( pDb==0 ) continue; + for(k=sqliteHashFirst(&pDb->tblHash); k; k=sqliteHashNext(k)){ + pTab = (Table*)sqliteHashData(k); + reindexTable(pParse, pTab, pColl); + } + } +} +#endif + +/* +** Generate code for the REINDEX command. +** +** REINDEX -- 1 +** REINDEX -- 2 +** REINDEX ?.? -- 3 +** REINDEX ?.? -- 4 +** +** Form 1 causes all indices in all attached databases to be rebuilt. +** Form 2 rebuilds all indices in all databases that use the named +** collating function. Forms 3 and 4 rebuild the named index or all +** indices associated with the named table. +*/ +#ifndef SQLITE_OMIT_REINDEX +void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ + CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ + char *z; /* Name of a table or index */ + const char *zDb; /* Name of the database */ + Table *pTab; /* A table in the database */ + Index *pIndex; /* An index associated with pTab */ + int iDb; /* The database index number */ + sqlite3 *db = pParse->db; /* The database connection */ + Token *pObjName; /* Name of the table or index to be reindexed */ + + /* Read the database schema. If an error occurs, leave an error message + ** and code in pParse and return NULL. */ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ + return; + } + + if( pName1==0 || pName1->z==0 ){ + reindexDatabases(pParse, 0); + return; + }else if( pName2==0 || pName2->z==0 ){ + pColl = sqlite3FindCollSeq(db, db->enc, pName1->z, pName1->n, 0); + if( pColl ){ + reindexDatabases(pParse, pColl); + return; + } + } + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + if( iDb<0 ) return; + z = sqlite3NameFromToken(pObjName); + zDb = db->aDb[iDb].zName; + pTab = sqlite3FindTable(db, z, zDb); + if( pTab ){ + reindexTable(pParse, pTab, 0); + sqliteFree(z); + return; + } + pIndex = sqlite3FindIndex(db, z, zDb); + sqliteFree(z); + if( pIndex ){ + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); + return; + } + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); +} +#endif diff --git a/db/sqlite3/src/config.h b/db/sqlite3/src/config.h index 2fda36b1e85..877f75ba548 100644 --- a/db/sqlite3/src/config.h +++ b/db/sqlite3/src/config.h @@ -1,9 +1 @@ - -#ifndef _sqlite3_config_h -#define _sqlite3_config_h - -#include "prcpucfg.h" - -#define SQLITE_PTR_SZ PR_BYTES_PER_WORD - -#endif /* _sqlite3_config_h */ +#define SQLITE_PTR_SZ 4 diff --git a/db/sqlite3/src/date.c b/db/sqlite3/src/date.c index 78e53e5a44d..52075691616 100644 --- a/db/sqlite3/src/date.c +++ b/db/sqlite3/src/date.c @@ -16,7 +16,7 @@ ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.37 2004/10/06 15:41:16 drh Exp $ +** $Id: date.c,v 1.44 2005/03/21 00:43:44 drh Exp $ ** ** NOTES: ** @@ -272,7 +272,7 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ return 1; } zDate += 10; - while( isspace(*(u8*)zDate) ){ zDate++; } + while( isspace(*(u8*)zDate) || 'T'==*(u8*)zDate ){ zDate++; } if( parseHhMmSs(zDate, p)==0 ){ /* We got the time */ }else if( *zDate==0 ){ @@ -315,12 +315,10 @@ static int parseDateOrTime(const char *zDate, DateTime *p){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ double r; - if( sqlite3OsCurrentTime(&r)==0 ){ - p->rJD = r; - p->validJD = 1; - return 0; - } - return 1; + sqlite3OsCurrentTime(&r); + p->rJD = r; + p->validJD = 1; + return 0; }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){ p->rJD = sqlite3AtoF(zDate, 0); p->validJD = 1; @@ -862,9 +860,100 @@ static void strftimeFunc( } } +/* +** current_time() +** +** This function returns the same value as time('now'). +*/ +static void ctimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_value *pVal = sqlite3ValueNew(); + if( pVal ){ + sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); + timeFunc(context, 1, &pVal); + sqlite3ValueFree(pVal); + } +} +/* +** current_date() +** +** This function returns the same value as date('now'). +*/ +static void cdateFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_value *pVal = sqlite3ValueNew(); + if( pVal ){ + sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); + dateFunc(context, 1, &pVal); + sqlite3ValueFree(pVal); + } +} + +/* +** current_timestamp() +** +** This function returns the same value as datetime('now'). +*/ +static void ctimestampFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_value *pVal = sqlite3ValueNew(); + if( pVal ){ + sqlite3ValueSetStr(pVal, -1, "now", SQLITE_UTF8, SQLITE_STATIC); + datetimeFunc(context, 1, &pVal); + sqlite3ValueFree(pVal); + } +} #endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */ +#ifdef SQLITE_OMIT_DATETIME_FUNCS +/* +** If the library is compiled to omit the full-scale date and time +** handling (to get a smaller binary), the following minimal version +** of the functions current_time(), current_date() and current_timestamp() +** are included instead. This is to support column declarations that +** include "DEFAULT CURRENT_TIME" etc. +** +** This function uses the C-library functions time(), gmtime() +** and strftime(). The format string to pass to strftime() is supplied +** as the user-data for the function. +*/ +static void currentTimeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + time_t t; + char *zFormat = (char *)sqlite3_user_data(context); + char zBuf[20]; + + time(&t); +#ifdef SQLITE_TEST + { + extern int sqlite3_current_time; /* See os_XXX.c */ + if( sqlite3_current_time ){ + t = sqlite3_current_time; + } + } +#endif + + sqlite3OsEnterMutex(); + strftime(zBuf, 20, zFormat, gmtime(&t)); + sqlite3OsLeaveMutex(); + + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); +} +#endif + /* ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with @@ -882,6 +971,9 @@ void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ { "time", -1, timeFunc }, { "datetime", -1, datetimeFunc }, { "strftime", -1, strftimeFunc }, + { "current_time", 0, ctimeFunc }, + { "current_timestamp", 0, ctimestampFunc }, + { "current_date", 0, cdateFunc }, }; int i; @@ -889,5 +981,20 @@ void sqlite3RegisterDateTimeFunctions(sqlite3 *db){ sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0); } +#else + static const struct { + char *zName; + char *zFormat; + } aFuncs[] = { + { "current_time", "%H:%M:%S" }, + { "current_date", "%Y-%m-%d" }, + { "current_timestamp", "%Y-%m-%d %H:%M:%S" } + }; + int i; + + for(i=0; ireadOnly ){ + if( pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0 + && pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } +#ifndef SQLITE_OMIT_VIEW if( !viewOk && pTab->pSelect ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } +#endif return 0; } @@ -65,7 +68,11 @@ void sqlite3OpenTableForReading( /* -** Process a DELETE FROM statement. +** Generate code for a DELETE FROM statement. +** +** DELETE FROM table_wxyz WHERE a<5 AND b NOT NULL; +** \________/ \________________/ +** pTabList pWhere */ void sqlite3DeleteFrom( Parse *pParse, /* The parser context */ @@ -81,17 +88,17 @@ void sqlite3DeleteFrom( Index *pIdx; /* For looping over indices of the table */ int iCur; /* VDBE Cursor number for pTab */ sqlite3 *db; /* Main database structure */ - int isView; /* True if attempting to delete from a view */ AuthContext sContext; /* Authorization context */ + int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ + NameContext sNC; /* Name context to resolve expressions in */ - int row_triggers_exist = 0; /* True if any triggers exist */ - int before_triggers; /* True if there are BEFORE triggers */ - int after_triggers; /* True if there are AFTER triggers */ - int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to delete from a view */ + int triggers_exist = 0; /* True if any triggers exist */ +#endif sContext.pParse = 0; if( pParse->nErr || sqlite3_malloc_failed ){ - pTabList = 0; goto delete_from_cleanup; } db = pParse->db; @@ -104,13 +111,23 @@ void sqlite3DeleteFrom( */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto delete_from_cleanup; - before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, - TK_DELETE, TK_BEFORE, TK_ROW, 0); - after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, - TK_DELETE, TK_AFTER, TK_ROW, 0); - row_triggers_exist = before_triggers || after_triggers; + + /* Figure out if we have any triggers and if the table being + ** deleted from is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0); isView = pTab->pSelect!=0; - if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ +#else +# define triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + + if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto delete_from_cleanup; } assert( pTab->iDbnDb ); @@ -127,15 +144,18 @@ void sqlite3DeleteFrom( /* Allocate a cursor used to store the old.* data for a trigger. */ - if( row_triggers_exist ){ + if( triggers_exist ){ oldIdx = pParse->nTab++; } - /* Resolve the column names in all the expressions. + /* Resolve the column names in the WHERE clause. */ assert( pTabList->nSrc==1 ); iCur = pTabList->a[0].iCursor = pParse->nTab++; - if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pWhere, 0, 0) ){ + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + if( sqlite3ExprResolveNames(&sNC, pWhere) ){ goto delete_from_cleanup; } @@ -151,8 +171,8 @@ void sqlite3DeleteFrom( if( v==0 ){ goto delete_from_cleanup; } - sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, row_triggers_exist, pTab->iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, triggers_exist, pTab->iDb); /* If we are trying to delete from a view, construct that view into ** a temporary table. @@ -174,7 +194,7 @@ void sqlite3DeleteFrom( ** It is easier just to erase the whole table. Note, however, that ** this means that the row change count will be incorrect. */ - if( pWhere==0 && !row_triggers_exist ){ + if( pWhere==0 && !triggers_exist ){ if( db->flags & SQLITE_CountRows ){ /* If counting rows deleted, just count the total number of ** entries in the table. */ @@ -210,11 +230,12 @@ void sqlite3DeleteFrom( /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 1, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0); if( pWInfo==0 ) goto delete_from_cleanup; - /* Remember the key of every item to be deleted. + /* Remember the rowid of every item to be deleted. */ + sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); sqlite3VdbeAddOp(v, OP_ListWrite, 0, 0); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp(v, OP_AddImm, 1, 0); @@ -226,7 +247,7 @@ void sqlite3DeleteFrom( /* Open the pseudo-table used to store OLD if there are triggers. */ - if( row_triggers_exist ){ + if( triggers_exist ){ sqlite3VdbeAddOp(v, OP_OpenPseudo, oldIdx, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, oldIdx, pTab->nCol); } @@ -241,7 +262,7 @@ void sqlite3DeleteFrom( /* This is the beginning of the delete loop when there are ** row triggers. */ - if( row_triggers_exist ){ + if( triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); if( !isView ){ @@ -255,8 +276,8 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } - sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1, - oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, + (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_BEFORE, pTab, + -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, addr); } @@ -271,25 +292,25 @@ void sqlite3DeleteFrom( /* This is the beginning of the delete loop when there are no ** row triggers */ - if( !row_triggers_exist ){ + if( !triggers_exist ){ addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end); } /* Delete the row */ - sqlite3GenerateRowDelete(db, v, pTab, iCur, 1); + sqlite3GenerateRowDelete(db, v, pTab, iCur, pParse->nested==0); } /* If there are row triggers, close all cursors then invoke ** the AFTER triggers */ - if( row_triggers_exist ){ + if( triggers_exist ){ if( !isView ){ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); } sqlite3VdbeAddOp(v, OP_Close, iCur, 0); } - sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1, + (void)sqlite3CodeRowTrigger(pParse, TK_DELETE, 0, TRIGGER_AFTER, pTab, -1, oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default, addr); } @@ -300,7 +321,7 @@ void sqlite3DeleteFrom( sqlite3VdbeAddOp(v, OP_ListReset, 0, 0); /* Close the cursors after the loop if there are no row triggers */ - if( !row_triggers_exist ){ + if( !triggers_exist ){ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum); } @@ -309,9 +330,11 @@ void sqlite3DeleteFrom( } /* - ** Return the number of rows that were deleted. + ** Return the number of rows that were deleted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. */ - if( db->flags & SQLITE_CountRows ){ + if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, "rows deleted", P3_STATIC); @@ -412,6 +435,7 @@ void sqlite3GenerateIndexKey( sqlite3VdbeAddOp(v, OP_Dup, j, 0); }else{ sqlite3VdbeAddOp(v, OP_Column, iCur, idx); + sqlite3ColumnDefault(v, pTab, idx); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pIdx->nColumn, (1<<24)); diff --git a/db/sqlite3/src/expr.c b/db/sqlite3/src/expr.c index 75167579b3e..2971c02a9c2 100644 --- a/db/sqlite3/src/expr.c +++ b/db/sqlite3/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.166 2004/10/04 13:19:24 drh Exp $ +** $Id: expr.c,v 1.197 2005/03/21 03:53:38 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -62,8 +62,8 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ } /* -** pExpr is the left operand of a comparison operator. aff2 is the -** type affinity of the right operand. This routine returns the +** pExpr is an operand of a comparison operator. aff2 is the +** type affinity of the other operand. This routine returns the ** type affinity that should be used for the comparison operator. */ char sqlite3CompareAffinity(Expr *pExpr, char aff2){ @@ -179,16 +179,22 @@ static int codeCompare( ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. */ -Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ +Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, const Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ - /* When malloc fails, we leak memory from pLeft and pRight */ + /* When malloc fails, delete pLeft and pRight. Expressions passed to + ** this function must always be allocated with sqlite3Expr() for this + ** reason. + */ + sqlite3ExprDelete(pLeft); + sqlite3ExprDelete(pRight); return 0; } pNew->op = op; pNew->pLeft = pLeft; pNew->pRight = pRight; + pNew->iAgg = -1; if( pToken ){ assert( pToken->dyn==0 ); pNew->span = pNew->token = *pToken; @@ -198,6 +204,42 @@ Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){ return pNew; } +/* +** When doing a nested parse, you can include terms in an expression +** that look like this: #0 #1 #2 ... These terms refer to elements +** on the stack. "#0" (or just "#") means the top of the stack. +** "#1" means the next down on the stack. And so forth. #-1 means +** memory location 0. #-2 means memory location 1. And so forth. +** +** This routine is called by the parser to deal with on of those terms. +** It immediately generates code to store the value in a memory location. +** The returns an expression that will code to extract the value from +** that memory location as needed. +*/ +Expr *sqlite3RegisterExpr(Parse *pParse, Token *pToken){ + Vdbe *v = pParse->pVdbe; + Expr *p; + int depth; + if( v==0 ) return 0; + if( pParse->nested==0 ){ + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", pToken); + return 0; + } + p = sqlite3Expr(TK_REGISTER, 0, 0, pToken); + if( p==0 ){ + return 0; /* Malloc failed */ + } + depth = atoi(&pToken->z[1]); + if( depth>=0 ){ + p->iTable = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_Dup, depth, 0); + sqlite3VdbeAddOp(v, OP_MemStore, p->iTable, 1); + }else{ + p->iTable = -1-depth; + } + return p; +} + /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. @@ -238,7 +280,7 @@ Expr *sqlite3ExprFunction(ExprList *pList, Token *pToken){ Expr *pNew; pNew = sqliteMalloc( sizeof(Expr) ); if( pNew==0 ){ - /* sqlite3ExprListDelete(pList); // Leak pList when malloc fails */ + sqlite3ExprListDelete(pList); /* Avoid leaking memory when malloc fails */ return 0; } pNew->op = TK_FUNCTION; @@ -356,7 +398,7 @@ Expr *sqlite3ExprDup(Expr *p){ if( pNew==0 ) return 0; memcpy(pNew, p, sizeof(*pNew)); if( p->token.z!=0 ){ - pNew->token.z = sqliteStrDup(p->token.z); + pNew->token.z = sqliteStrNDup(p->token.z, p->token.n); pNew->token.dyn = 1; }else{ assert( pNew->token.z==0 ); @@ -366,6 +408,7 @@ Expr *sqlite3ExprDup(Expr *p){ pNew->pRight = sqlite3ExprDup(p->pRight); pNew->pList = sqlite3ExprListDup(p->pList); pNew->pSelect = sqlite3SelectDup(p->pSelect); + pNew->pTab = p->pTab; return pNew; } void sqlite3TokenCopy(Token *pTo, Token *pFrom){ @@ -410,6 +453,15 @@ ExprList *sqlite3ExprListDup(ExprList *p){ } return pNew; } + +/* +** If cursors, triggers, views and subqueries are all omitted from +** the build, then none of the following routines, except for +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes +** called with a NULL argument. +*/ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ + || !defined(SQLITE_OMIT_SUBQUERY) SrcList *sqlite3SrcListDup(SrcList *p){ SrcList *pNew; int i; @@ -427,10 +479,14 @@ SrcList *sqlite3SrcListDup(SrcList *p){ pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias); pNewItem->jointype = pOldItem->jointype; pNewItem->iCursor = pOldItem->iCursor; - pNewItem->pTab = 0; + pNewItem->pTab = pOldItem->pTab; + if( pNewItem->pTab ){ + pNewItem->pTab->isTransient = 0; + } pNewItem->pSelect = sqlite3SelectDup(pOldItem->pSelect); pNewItem->pOn = sqlite3ExprDup(pOldItem->pOn); pNewItem->pUsing = sqlite3IdListDup(pOldItem->pUsing); + pNewItem->colUsed = pOldItem->colUsed; } return pNew; } @@ -442,7 +498,10 @@ IdList *sqlite3IdListDup(IdList *p){ if( pNew==0 ) return 0; pNew->nId = pNew->nAlloc = p->nId; pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) ); - if( pNew->a==0 ) return 0; + if( pNew->a==0 ){ + sqliteFree(pNew); + return 0; + } for(i=0; inId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; @@ -465,14 +524,22 @@ Select *sqlite3SelectDup(Select *p){ pNew->pOrderBy = sqlite3ExprListDup(p->pOrderBy); pNew->op = p->op; pNew->pPrior = sqlite3SelectDup(p->pPrior); - pNew->nLimit = p->nLimit; - pNew->nOffset = p->nOffset; - pNew->zSelect = 0; + pNew->pLimit = sqlite3ExprDup(p->pLimit); + pNew->pOffset = sqlite3ExprDup(p->pOffset); pNew->iLimit = -1; pNew->iOffset = -1; pNew->ppOpenTemp = 0; + pNew->pFetch = 0; + pNew->isResolved = p->isResolved; + pNew->isAgg = p->isAgg; return pNew; } +#else +Select *sqlite3SelectDup(Select *p){ + assert( p==0 ); + return 0; +} +#endif /* @@ -483,28 +550,34 @@ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ if( pList==0 ){ pList = sqliteMalloc( sizeof(ExprList) ); if( pList==0 ){ - /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */ - return 0; + goto no_mem; } assert( pList->nAlloc==0 ); } if( pList->nAlloc<=pList->nExpr ){ - pList->nAlloc = pList->nAlloc*2 + 4; - pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0])); - if( pList->a==0 ){ - /* sqlite3ExprDelete(pExpr); // Leak memory if malloc fails */ - pList->nExpr = pList->nAlloc = 0; - return pList; + struct ExprList_item *a; + int n = pList->nAlloc*2 + 4; + a = sqliteRealloc(pList->a, n*sizeof(pList->a[0])); + if( a==0 ){ + goto no_mem; } + pList->a = a; + pList->nAlloc = n; } assert( pList->a!=0 ); if( pExpr || pName ){ struct ExprList_item *pItem = &pList->a[pList->nExpr++]; memset(pItem, 0, sizeof(*pItem)); - pItem->pExpr = pExpr; pItem->zName = sqlite3NameFromToken(pName); + pItem->pExpr = pExpr; } return pList; + +no_mem: + /* Avoid leaking memory if malloc has failed. */ + sqlite3ExprDelete(pExpr); + sqlite3ExprListDelete(pList); + return 0; } /* @@ -524,6 +597,89 @@ void sqlite3ExprListDelete(ExprList *pList){ sqliteFree(pList); } +/* +** Walk an expression tree. Call xFunc for each node visited. +** +** The return value from xFunc determines whether the tree walk continues. +** 0 means continue walking the tree. 1 means do not walk children +** of the current node but continue with siblings. 2 means abandon +** the tree walk completely. +** +** The return value from this routine is 1 to abandon the tree walk +** and 0 to continue. +*/ +static int walkExprList(ExprList *, int (*)(void *, Expr*), void *); +static int walkExprTree(Expr *pExpr, int (*xFunc)(void*,Expr*), void *pArg){ + int rc; + if( pExpr==0 ) return 0; + rc = (*xFunc)(pArg, pExpr); + if( rc==0 ){ + if( walkExprTree(pExpr->pLeft, xFunc, pArg) ) return 1; + if( walkExprTree(pExpr->pRight, xFunc, pArg) ) return 1; + if( walkExprList(pExpr->pList, xFunc, pArg) ) return 1; + } + return rc>1; +} + +/* +** Call walkExprTree() for every expression in list p. +*/ +static int walkExprList(ExprList *p, int (*xFunc)(void *, Expr*), void *pArg){ + int i; + struct ExprList_item *pItem; + if( !p ) return 0; + for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ + if( walkExprTree(pItem->pExpr, xFunc, pArg) ) return 1; + } + return 0; +} + +/* +** Call walkExprTree() for every expression in Select p, not including +** expressions that are part of sub-selects in any FROM clause or the LIMIT +** or OFFSET expressions.. +*/ +static int walkSelectExpr(Select *p, int (*xFunc)(void *, Expr*), void *pArg){ + walkExprList(p->pEList, xFunc, pArg); + walkExprTree(p->pWhere, xFunc, pArg); + walkExprList(p->pGroupBy, xFunc, pArg); + walkExprTree(p->pHaving, xFunc, pArg); + walkExprList(p->pOrderBy, xFunc, pArg); + return 0; +} + + +/* +** This routine is designed as an xFunc for walkExprTree(). +** +** pArg is really a pointer to an integer. If we can tell by looking +** at pExpr that the expression that contains pExpr is not a constant +** expression, then set *pArg to 0 and return 2 to abandon the tree walk. +** If pExpr does does not disqualify the expression from being a constant +** then do nothing. +** +** After walking the whole tree, if no nodes are found that disqualify +** the expression as constant, then we assume the whole expression +** is constant. See sqlite3ExprIsConstant() for additional information. +*/ +static int exprNodeIsConstant(void *pArg, Expr *pExpr){ + switch( pExpr->op ){ + case TK_ID: + case TK_COLUMN: + case TK_DOT: + case TK_AGG_FUNCTION: + case TK_FUNCTION: +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: +#endif + *((int*)pArg) = 0; + return 2; + default: + return 0; + } +} + /* ** Walk an expression tree. Return 1 if the expression is constant ** and 0 if it involves variables. @@ -533,36 +689,13 @@ void sqlite3ExprListDelete(ExprList *pList){ ** a constant. */ int sqlite3ExprIsConstant(Expr *p){ - switch( p->op ){ - case TK_ID: - case TK_COLUMN: - case TK_DOT: - case TK_FUNCTION: - return 0; - case TK_NULL: - case TK_STRING: - case TK_BLOB: - case TK_INTEGER: - case TK_FLOAT: - case TK_VARIABLE: - return 1; - default: { - if( p->pLeft && !sqlite3ExprIsConstant(p->pLeft) ) return 0; - if( p->pRight && !sqlite3ExprIsConstant(p->pRight) ) return 0; - if( p->pList ){ - int i; - for(i=0; ipList->nExpr; i++){ - if( !sqlite3ExprIsConstant(p->pList->a[i].pExpr) ) return 0; - } - } - return p->pLeft!=0 || p->pRight!=0 || (p->pList && p->pList->nExpr>0); - } - } - return 0; + int isConst = 1; + walkExprTree(p, exprNodeIsConstant, &isConst); + return isConst; } /* -** If the given expression codes a constant integer that is small enough +** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. @@ -575,16 +708,6 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){ } break; } - case TK_STRING: { - const u8 *z = (u8*)p->token.z; - int n = p->token.n; - if( n>0 && z[0]=='-' ){ z++; n--; } - while( n>0 && *z && isdigit(*z) ){ z++; n--; } - if( n==0 && sqlite3GetInt32(p->token.z, pValue) ){ - return 1; - } - break; - } case TK_UPLUS: { return sqlite3ExprIsInteger(p->pLeft, pValue); } @@ -641,8 +764,7 @@ static int lookupName( Token *pDbToken, /* Name of the database containing table, or NULL */ Token *pTableToken, /* Name of table containing column, or NULL */ Token *pColumnToken, /* Name of the column. */ - SrcList *pSrcList, /* List of tables used to resolve column names */ - ExprList *pEList, /* List of expressions used to resolve "AS" */ + NameContext *pNC, /* The name context used to resolve the name */ Expr *pExpr /* Make this EXPR node point to the selected column */ ){ char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */ @@ -652,122 +774,144 @@ static int lookupName( int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ sqlite3 *db = pParse->db; /* The database */ + struct SrcList_item *pItem; /* Use for looping over pSrcList items */ + struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + NameContext *pTopNC = pNC; /* First namecontext in the list */ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */ zDb = sqlite3NameFromToken(pDbToken); zTab = sqlite3NameFromToken(pTableToken); zCol = sqlite3NameFromToken(pColumnToken); if( sqlite3_malloc_failed ){ - return 1; /* Leak memory (zDb and zTab) if malloc fails */ + goto lookupname_end; } - assert( zTab==0 || pEList==0 ); pExpr->iTable = -1; - for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrcList->a[i]; - Table *pTab = pItem->pTab; - Column *pCol; + while( pNC && cnt==0 ){ + SrcList *pSrcList = pNC->pSrcList; + ExprList *pEList = pNC->pEList; - if( pTab==0 ) continue; - assert( pTab->nCol>0 ); - if( zTab ){ - if( pItem->zAlias ){ - char *zTabName = pItem->zAlias; - if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - }else{ - char *zTabName = pTab->zName; - if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; - if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ - continue; + pNC->nRef++; + /* assert( zTab==0 || pEList==0 ); */ + if( pSrcList ){ + for(i=0, pItem=pSrcList->a; inSrc; i++, pItem++){ + Table *pTab = pItem->pTab; + Column *pCol; + + if( pTab==0 ) continue; + assert( pTab->nCol>0 ); + if( zTab ){ + if( pItem->zAlias ){ + char *zTabName = pItem->zAlias; + if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + }else{ + char *zTabName = pTab->zName; + if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + if( zDb!=0 && sqlite3StrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){ + continue; + } + } + } + if( 0==(cntTab++) ){ + pExpr->iTable = pItem->iCursor; + pExpr->iDb = pTab->iDb; + pMatch = pItem; + } + for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + cnt++; + pExpr->iTable = pItem->iCursor; + pMatch = pItem; + pExpr->iDb = pTab->iDb; + /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ + pExpr->iColumn = j==pTab->iPKey ? -1 : j; + pExpr->affinity = pTab->aCol[j].affinity; + pExpr->pColl = pTab->aCol[j].pColl; + break; + } } } } - if( 0==(cntTab++) ){ - pExpr->iTable = pItem->iCursor; - pExpr->iDb = pTab->iDb; - } - for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - cnt++; - pExpr->iTable = pItem->iCursor; + +#ifndef SQLITE_OMIT_TRIGGER + /* If we have not already resolved the name, then maybe + ** it is a new.* or old.* trigger argument reference + */ + if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ + TriggerStack *pTriggerStack = pParse->trigStack; + Table *pTab = 0; + if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){ + pExpr->iTable = pTriggerStack->newIdx; + assert( pTriggerStack->pTab ); + pTab = pTriggerStack->pTab; + }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){ + pExpr->iTable = pTriggerStack->oldIdx; + assert( pTriggerStack->pTab ); + pTab = pTriggerStack->pTab; + } + + if( pTab ){ + int j; + Column *pCol = pTab->aCol; + pExpr->iDb = pTab->iDb; - /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; - break; - } - } - } - - /* If we have not already resolved the name, then maybe - ** it is a new.* or old.* trigger argument reference - */ - if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ - TriggerStack *pTriggerStack = pParse->trigStack; - Table *pTab = 0; - if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){ - pExpr->iTable = pTriggerStack->newIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab) == 0 ){ - pExpr->iTable = pTriggerStack->oldIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - } - - if( pTab ){ - int j; - Column *pCol = pTab->aCol; - - pExpr->iDb = pTab->iDb; - cntTab++; - for(j=0; j < pTab->nCol; j++, pCol++) { - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - cnt++; - pExpr->iColumn = j==pTab->iPKey ? -1 : j; - pExpr->affinity = pTab->aCol[j].affinity; - pExpr->pColl = pTab->aCol[j].pColl; - break; + cntTab++; + for(j=0; j < pTab->nCol; j++, pCol++) { + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + cnt++; + pExpr->iColumn = j==pTab->iPKey ? -1 : j; + pExpr->affinity = pTab->aCol[j].affinity; + pExpr->pColl = pTab->aCol[j].pColl; + pExpr->pTab = pTab; + break; + } } } } - } +#endif /* !defined(SQLITE_OMIT_TRIGGER) */ - /* - ** Perhaps the name is a reference to the ROWID - */ - if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ - cnt = 1; - pExpr->iColumn = -1; - pExpr->affinity = SQLITE_AFF_INTEGER; - } + /* + ** Perhaps the name is a reference to the ROWID + */ + if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) ){ + cnt = 1; + pExpr->iColumn = -1; + pExpr->affinity = SQLITE_AFF_INTEGER; + } - /* - ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z - ** might refer to an result-set alias. This happens, for example, when - ** we are resolving names in the WHERE clause of the following command: - ** - ** SELECT a+b AS x FROM table WHERE x<10; - ** - ** In cases like this, replace pExpr with a copy of the expression that - ** forms the result set entry ("a+b" in the example) and return immediately. - ** Note that the expression in the result set should have already been - ** resolved by the time the WHERE clause is resolved. - */ - if( cnt==0 && pEList!=0 ){ - for(j=0; jnExpr; j++){ - char *zAs = pEList->a[j].zName; - if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ - assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - pExpr->op = TK_AS; - pExpr->iColumn = j; - pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr); - sqliteFree(zCol); - assert( zTab==0 && zDb==0 ); - return 0; - } - } + /* + ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z + ** might refer to an result-set alias. This happens, for example, when + ** we are resolving names in the WHERE clause of the following command: + ** + ** SELECT a+b AS x FROM table WHERE x<10; + ** + ** In cases like this, replace pExpr with a copy of the expression that + ** forms the result set entry ("a+b" in the example) and return immediately. + ** Note that the expression in the result set should have already been + ** resolved by the time the WHERE clause is resolved. + */ + if( cnt==0 && pEList!=0 && zTab==0 ){ + for(j=0; jnExpr; j++){ + char *zAs = pEList->a[j].zName; + if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){ + assert( pExpr->pLeft==0 && pExpr->pRight==0 ); + pExpr->op = TK_AS; + pExpr->iColumn = j; + pExpr->pLeft = sqlite3ExprDup(pEList->a[j].pExpr); + sqliteFree(zCol); + assert( zTab==0 && zDb==0 ); + return 0; + } + } + } + + /* Advance to the next name context. The loop will exit when either + ** we have a match (cnt>0) or when we run out of name contexts. + */ + if( cnt==0 ){ + pNC = pNC->pNext; + } } /* @@ -799,8 +943,25 @@ static int lookupName( } sqlite3ErrorMsg(pParse, zErr, z); sqliteFree(z); + pTopNC->nErr++; } + /* If a column from a table in pSrcList is referenced, then record + ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes + ** bit 0 to be set. Column 1 sets bit 1. And so forth. If the + ** column number is greater than the number of bits in the bitmask + ** then set the high-order bit of the bitmask. + */ + if( pExpr->iColumn>=0 && pMatch!=0 ){ + int n = pExpr->iColumn; + if( n>=sizeof(Bitmask)*8 ){ + n = sizeof(Bitmask)*8-1; + } + assert( pMatch->iCursor==pExpr->iTable ); + pMatch->colUsed |= 1<pRight); pExpr->pRight = 0; pExpr->op = TK_COLUMN; - sqlite3AuthRead(pParse, pExpr, pSrcList); + if( cnt==1 ){ + assert( pNC!=0 ); + sqlite3AuthRead(pParse, pExpr, pNC->pSrcList); + if( pMatch && !pMatch->pSelect ){ + pExpr->pTab = pMatch->pTab; + } + } return cnt!=1; } +/* +** pExpr is a node that defines a function of some kind. It might +** be a syntactic function like "count(x)" or it might be a function +** that implements an operator, like "a LIKE b". +** +** This routine makes *pzName point to the name of the function and +** *pnName hold the number of characters in the function name. +*/ +static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ + switch( pExpr->op ){ + case TK_FUNCTION: { + *pzName = pExpr->token.z; + *pnName = pExpr->token.n; + break; + } + case TK_LIKE: { + *pzName = "like"; + *pnName = 4; + break; + } + case TK_GLOB: { + *pzName = "glob"; + *pnName = 4; + break; + } + case TK_CTIME: { + *pzName = "current_time"; + *pnName = 12; + break; + } + case TK_CDATE: { + *pzName = "current_date"; + *pnName = 12; + break; + } + case TK_CTIMESTAMP: { + *pzName = "current_timestamp"; + *pnName = 17; + break; + } + } +} + +/* +** This routine is designed as an xFunc for walkExprTree(). +** +** Resolve symbolic names into TK_COLUMN operators for the current +** node in the expression tree. Return 0 to continue the search down +** the tree or 2 to abort the tree walk. +** +** This routine also does error checking and name resolution for +** function names. The operator for aggregate functions is changed +** to TK_AGG_FUNCTION. +*/ +static int nameResolverStep(void *pArg, Expr *pExpr){ + NameContext *pNC = (NameContext*)pArg; + SrcList *pSrcList; + Parse *pParse; + + if( pExpr==0 ) return 1; + assert( pNC!=0 ); + pSrcList = pNC->pSrcList; + pParse = pNC->pParse; + + if( ExprHasAnyProperty(pExpr, EP_Resolved) ) return 1; + ExprSetProperty(pExpr, EP_Resolved); +#ifndef NDEBUG + if( pSrcList ){ + int i; + for(i=0; inSrc; i++){ + assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab); + } + } +#endif + switch( pExpr->op ){ + /* Double-quoted strings (ex: "abc") are used as identifiers if + ** possible. Otherwise they remain as strings. Single-quoted + ** strings (ex: 'abc') are always string literals. + */ + case TK_STRING: { + if( pExpr->token.z[0]=='\'' ) break; + /* Fall thru into the TK_ID case if this is a double-quoted string */ + } + /* A lone identifier is the name of a column. + */ + case TK_ID: { + lookupName(pParse, 0, 0, &pExpr->token, pNC, pExpr); + return 1; + } + + /* A table name and column name: ID.ID + ** Or a database, table and column: ID.ID.ID + */ + case TK_DOT: { + Token *pColumn; + Token *pTable; + Token *pDb; + Expr *pRight; + + /* if( pSrcList==0 ) break; */ + pRight = pExpr->pRight; + if( pRight->op==TK_ID ){ + pDb = 0; + pTable = &pExpr->pLeft->token; + pColumn = &pRight->token; + }else{ + assert( pRight->op==TK_DOT ); + pDb = &pExpr->pLeft->token; + pTable = &pRight->pLeft->token; + pColumn = &pRight->pRight->token; + } + lookupName(pParse, pDb, pTable, pColumn, pNC, pExpr); + return 1; + } + + /* Resolve function names + */ + case TK_CTIME: + case TK_CTIMESTAMP: + case TK_CDATE: + case TK_GLOB: + case TK_LIKE: + case TK_FUNCTION: { + ExprList *pList = pExpr->pList; /* The argument list */ + int n = pList ? pList->nExpr : 0; /* Number of arguments */ + int no_such_func = 0; /* True if no such function exists */ + int wrong_num_args = 0; /* True if wrong number of arguments */ + int is_agg = 0; /* True if is an aggregate function */ + int i; + int nId; /* Number of characters in function name */ + const char *zId; /* The function name. */ + FuncDef *pDef; /* Information about the function */ + int enc = pParse->db->enc; /* The database encoding */ + + getFunctionName(pExpr, &zId, &nId); + pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); + if( pDef==0 ){ + pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); + if( pDef==0 ){ + no_such_func = 1; + }else{ + wrong_num_args = 1; + } + }else{ + is_agg = pDef->xFunc==0; + } + if( is_agg && !pNC->allowAgg ){ + sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); + pNC->nErr++; + is_agg = 0; + }else if( no_such_func ){ + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + pNC->nErr++; + }else if( wrong_num_args ){ + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + nId, zId); + pNC->nErr++; + } + if( is_agg ){ + pExpr->op = TK_AGG_FUNCTION; + pNC->hasAgg = 1; + } + if( is_agg ) pNC->allowAgg = 0; + for(i=0; pNC->nErr==0 && ia[i].pExpr, nameResolverStep, pNC); + } + if( is_agg ) pNC->allowAgg = 1; + /* FIX ME: Compute pExpr->affinity based on the expected return + ** type of the function + */ + return is_agg; + } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_SELECT: + case TK_EXISTS: +#endif + case TK_IN: { + if( pExpr->pSelect ){ + int nRef = pNC->nRef; + sqlite3SelectResolve(pParse, pExpr->pSelect, pNC); + assert( pNC->nRef>=nRef ); + if( nRef!=pNC->nRef ){ + ExprSetProperty(pExpr, EP_VarSelect); + } + } + } + } + return 0; +} + /* ** This routine walks an expression tree and resolves references to ** table columns. Nodes of the form ID.ID or ID resolve into an @@ -828,8 +1185,41 @@ static int lookupName( ** ROWID column is -1. Any INTEGER PRIMARY KEY column is tried as an ** alias for ROWID. ** -** We also check for instances of the IN operator. IN comes in two -** forms: +** Also resolve function names and check the functions for proper +** usage. Make sure all function names are recognized and all functions +** have the correct number of arguments. Leave an error message +** in pParse->zErrMsg if anything is amiss. Return the number of errors. +** +** If the expression contains aggregate functions then set the EP_Agg +** property on the expression. +*/ +int sqlite3ExprResolveNames( + NameContext *pNC, /* Namespace to resolve expressions in. */ + Expr *pExpr /* The expression to be analyzed. */ +){ + if( pExpr==0 ) return 0; + walkExprTree(pExpr, nameResolverStep, pNC); + if( pNC->nErr>0 ){ + ExprSetProperty(pExpr, EP_Error); + } + return ExprHasProperty(pExpr, EP_Error); +} + +/* +** A pointer instance of this structure is used to pass information +** through walkExprTree into codeSubqueryStep(). +*/ +typedef struct QueryCoder QueryCoder; +struct QueryCoder { + Parse *pParse; /* The parsing context */ + NameContext *pNC; /* Namespace of first enclosing query */ +}; + + +/* +** Generate code for subqueries and IN operators. +** +** IN operators comes in two forms: ** ** expr IN (exprlist) ** and @@ -838,80 +1228,36 @@ static int lookupName( ** The first form is handled by creating a set holding the list ** of allowed values. The second form causes the SELECT to generate ** a temporary table. -** -** This routine also looks for scalar SELECTs that are part of an expression. -** If it finds any, it generates code to write the value of that select -** into a memory cell. -** -** Unknown columns or tables provoke an error. The function returns -** the number of errors seen and leaves an error message on pParse->zErrMsg. */ -int sqlite3ExprResolveIds( - Parse *pParse, /* The parser context */ - SrcList *pSrcList, /* List of tables used to resolve column names */ - ExprList *pEList, /* List of expressions used to resolve "AS" */ - Expr *pExpr /* The expression to be analyzed. */ -){ - int i; +#ifndef SQLITE_OMIT_SUBQUERY +void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ + int label = 0; /* Address after sub-select code */ + Vdbe *v = sqlite3GetVdbe(pParse); + if( v==0 ) return; - if( pExpr==0 || pSrcList==0 ) return 0; - for(i=0; inSrc; i++){ - assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursornTab ); + /* If this is not a variable (correlated) select, then execute + ** it only once. Unless this is part of a trigger program. In + ** that case re-execute every time (this could be optimized). + */ + if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ + int mem = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0); + label = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp(v, OP_If, 0, label); + sqlite3VdbeAddOp(v, OP_Integer, 1, 0); + sqlite3VdbeAddOp(v, OP_MemStore, mem, 1); } + + if( pExpr->pSelect ){ + sqlite3VdbeAddOp(v, OP_AggContextPush, 0, 0); + } + switch( pExpr->op ){ - /* Double-quoted strings (ex: "abc") are used as identifiers if - ** possible. Otherwise they remain as strings. Single-quoted - ** strings (ex: 'abc') are always string literals. - */ - case TK_STRING: { - if( pExpr->token.z[0]=='\'' ) break; - /* Fall thru into the TK_ID case if this is a double-quoted string */ - } - /* A lone identifier is the name of a columnd. - */ - case TK_ID: { - if( lookupName(pParse, 0, 0, &pExpr->token, pSrcList, pEList, pExpr) ){ - return 1; - } - break; - } - - /* A table name and column name: ID.ID - ** Or a database, table and column: ID.ID.ID - */ - case TK_DOT: { - Token *pColumn; - Token *pTable; - Token *pDb; - Expr *pRight; - - pRight = pExpr->pRight; - if( pRight->op==TK_ID ){ - pDb = 0; - pTable = &pExpr->pLeft->token; - pColumn = &pRight->token; - }else{ - assert( pRight->op==TK_DOT ); - pDb = &pExpr->pLeft->token; - pTable = &pRight->pLeft->token; - pColumn = &pRight->pRight->token; - } - if( lookupName(pParse, pDb, pTable, pColumn, pSrcList, 0, pExpr) ){ - return 1; - } - break; - } - case TK_IN: { char affinity; - Vdbe *v = sqlite3GetVdbe(pParse); KeyInfo keyInfo; int addr; /* Address of OP_OpenTemp instruction */ - if( v==0 ) return 1; - if( sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){ - return 1; - } affinity = sqlite3ExprAffinity(pExpr->pLeft); /* Whether this is an 'x IN(SELECT...)' or an 'x IN()' @@ -970,10 +1316,7 @@ int sqlite3ExprResolveIds( if( !sqlite3ExprIsConstant(pE2) ){ sqlite3ErrorMsg(pParse, "right-hand side of IN operator must be constant"); - return 1; - } - if( sqlite3ExprCheck(pParse, pE2, 0, 0) ){ - return 1; + return; } /* Evaluate the expression and insert it into the temp table */ @@ -984,183 +1327,43 @@ int sqlite3ExprResolveIds( } } sqlite3VdbeChangeP3(v, addr, (void *)&keyInfo, P3_KEYINFO); - break; } + case TK_EXISTS: case TK_SELECT: { /* This has to be a scalar SELECT. Generate code to put the ** value of this select in a memory cell and record the number ** of the memory cell in iColumn. */ + int sop; + Select *pSel; + pExpr->iColumn = pParse->nMem++; - if(sqlite3Select(pParse, pExpr->pSelect, SRT_Mem,pExpr->iColumn,0,0,0,0)){ - return 1; - } - break; - } - - /* For all else, just recursively walk the tree */ - default: { - if( pExpr->pLeft - && sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){ - return 1; - } - if( pExpr->pRight - && sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pRight) ){ - return 1; - } - if( pExpr->pList ){ - int i; - ExprList *pList = pExpr->pList; - for(i=0; inExpr; i++){ - Expr *pArg = pList->a[i].pExpr; - if( sqlite3ExprResolveIds(pParse, pSrcList, pEList, pArg) ){ - return 1; - } - } - } - } - } - return 0; -} - -/* -** pExpr is a node that defines a function of some kind. It might -** be a syntactic function like "count(x)" or it might be a function -** that implements an operator, like "a LIKE b". -** -** This routine makes *pzName point to the name of the function and -** *pnName hold the number of characters in the function name. -*/ -static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){ - switch( pExpr->op ){ - case TK_FUNCTION: { - *pzName = pExpr->token.z; - *pnName = pExpr->token.n; - break; - } - case TK_LIKE: { - *pzName = "like"; - *pnName = 4; - break; - } - case TK_GLOB: { - *pzName = "glob"; - *pnName = 4; - break; - } - default: { - *pzName = "can't happen"; - *pnName = 12; - break; - } - } -} - -/* -** Error check the functions in an expression. Make sure all -** function names are recognized and all functions have the correct -** number of arguments. Leave an error message in pParse->zErrMsg -** if anything is amiss. Return the number of errors. -** -** if pIsAgg is not null and this expression is an aggregate function -** (like count(*) or max(value)) then write a 1 into *pIsAgg. -*/ -int sqlite3ExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){ - int nErr = 0; - if( pExpr==0 ) return 0; - switch( pExpr->op ){ - case TK_GLOB: - case TK_LIKE: - case TK_FUNCTION: { - int n = pExpr->pList ? pExpr->pList->nExpr : 0; /* Number of arguments */ - int no_such_func = 0; /* True if no such function exists */ - int wrong_num_args = 0; /* True if wrong number of arguments */ - int is_agg = 0; /* True if is an aggregate function */ - int i; - int nId; /* Number of characters in function name */ - const char *zId; /* The function name. */ - FuncDef *pDef; - int enc = pParse->db->enc; - - getFunctionName(pExpr, &zId, &nId); - pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0); - if( pDef==0 ){ - pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, enc, 0); - if( pDef==0 ){ - no_such_func = 1; - }else{ - wrong_num_args = 1; - } + pSel = pExpr->pSelect; + if( pExpr->op==TK_SELECT ){ + sop = SRT_Mem; }else{ - is_agg = pDef->xFunc==0; - } - if( is_agg && !allowAgg ){ - sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId); - nErr++; - is_agg = 0; - }else if( no_such_func ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - nErr++; - }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); - nErr++; - } - if( is_agg ){ - pExpr->op = TK_AGG_FUNCTION; - if( pIsAgg ) *pIsAgg = 1; - } - for(i=0; nErr==0 && ipList->a[i].pExpr, - allowAgg && !is_agg, pIsAgg); - } - /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function - */ - } - default: { - if( pExpr->pLeft ){ - nErr = sqlite3ExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg); - } - if( nErr==0 && pExpr->pRight ){ - nErr = sqlite3ExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg); - } - if( nErr==0 && pExpr->pList ){ - int n = pExpr->pList->nExpr; - int i; - for(i=0; nErr==0 && ipList->a[i].pExpr; - nErr = sqlite3ExprCheck(pParse, pE2, allowAgg, pIsAgg); - } + static const Token one = { "1", 0, 1 }; + sop = SRT_Exists; + sqlite3ExprListDelete(pSel->pEList); + pSel->pEList = sqlite3ExprListAppend(0, + sqlite3Expr(TK_INTEGER, 0, 0, &one), 0); } + sqlite3Select(pParse, pSel, sop, pExpr->iColumn, 0, 0, 0, 0); break; } } - return nErr; -} -/* -** Call sqlite3ExprResolveIds() followed by sqlite3ExprCheck(). -** -** This routine is provided as a convenience since it is very common -** to call ResolveIds() and Check() back to back. -*/ -int sqlite3ExprResolveAndCheck( - Parse *pParse, /* The parser context */ - SrcList *pSrcList, /* List of tables used to resolve column names */ - ExprList *pEList, /* List of expressions used to resolve "AS" */ - Expr *pExpr, /* The expression to be analyzed. */ - int allowAgg, /* True to allow aggregate expressions */ - int *pIsAgg /* Set to TRUE if aggregates are found */ -){ - if( pExpr==0 ) return 0; - if( sqlite3ExprResolveIds(pParse,pSrcList,pEList,pExpr) ){ - return 1; + if( pExpr->pSelect ){ + sqlite3VdbeAddOp(v, OP_AggContextPop, 0, 0); } - return sqlite3ExprCheck(pParse, pExpr, allowAgg, pIsAgg); + if( label<0 ){ + sqlite3VdbeResolveLabel(v, label); + } + return; } +#endif /* SQLITE_OMIT_SUBQUERY */ /* ** Generate an instruction that will put the integer describe by @@ -1190,19 +1393,19 @@ static void codeInteger(Vdbe *v, const char *z, int n){ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ Vdbe *v = pParse->pVdbe; int op; - if( v==0 || pExpr==0 ) return; + if( v==0 ) return; + if( pExpr==0 ){ + sqlite3VdbeAddOp(v, OP_String8, 0, 0); /* Empty expression evals to NULL */ + return; + } op = pExpr->op; switch( op ){ case TK_COLUMN: { - if( pParse->useAgg ){ - sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); + if( !pParse->fillAgg && pExpr->iAgg>=0 ){ + sqlite3VdbeAddOp(v, OP_AggGet, pExpr->iAggCtx, pExpr->iAgg); }else if( pExpr->iColumn>=0 ){ sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); -#ifndef NDEBUG - if( pExpr->span.z && pExpr->span.n>0 && pExpr->span.n<100 ){ - VdbeComment((v, "# %T", &pExpr->span)); - } -#endif + sqlite3ColumnDefault(v, pExpr->pTab, pExpr->iColumn); }else{ sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0); } @@ -1220,12 +1423,14 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeDequoteP3(v, -1); break; } +#ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { assert( TK_BLOB==OP_HexBlob ); sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1); sqlite3VdbeDequoteP3(v, -1); break; } +#endif case TK_NULL: { sqlite3VdbeAddOp(v, OP_String8, 0, 0); break; @@ -1237,6 +1442,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ } break; } + case TK_REGISTER: { + sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0); + break; + } case TK_LT: case TK_LE: case TK_GT: @@ -1323,6 +1532,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; } + case TK_CDATE: + case TK_CTIME: + case TK_CTIMESTAMP: case TK_GLOB: case TK_LIKE: case TK_FUNCTION: { @@ -1354,7 +1566,10 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF); break; } +#ifndef SQLITE_OMIT_SUBQUERY + case TK_EXISTS: case TK_SELECT: { + sqlite3CodeSubselect(pParse, pExpr); sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); VdbeComment((v, "# load subquery result")); break; @@ -1362,6 +1577,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_IN: { int addr; char affinity; + sqlite3CodeSubselect(pParse, pExpr); /* Figure out the affinity to use to create a key from the results ** of the expression. affinityStr stores a static string suitable for @@ -1386,6 +1602,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ break; } +#endif case TK_BETWEEN: { Expr *pLeft = pExpr->pLeft; struct ExprList_item *pLItem = pExpr->pList->a; @@ -1452,6 +1669,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ sqlite3VdbeResolveLabel(v, expr_end_label); break; } +#ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { if( !pParse->trigStack ){ sqlite3ErrorMsg(pParse, @@ -1472,10 +1690,38 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ VdbeComment((v, "# raise(IGNORE)")); } } +#endif break; } } +#ifndef SQLITE_OMIT_TRIGGER +/* +** Generate code that evalutes the given expression and leaves the result +** on the stack. See also sqlite3ExprCode(). +** +** This routine might also cache the result and modify the pExpr tree +** so that it will make use of the cached result on subsequent evaluations +** rather than evaluate the whole expression again. Trivial expressions are +** not cached. If the expression is cached, its result is stored in a +** memory location. +*/ +void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr){ + Vdbe *v = pParse->pVdbe; + int iMem; + int addr1, addr2; + if( v==0 ) return; + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3ExprCode(pParse, pExpr); + addr2 = sqlite3VdbeCurrentAddr(v); + if( addr2>addr1+1 || sqlite3VdbeGetOp(v, addr1)->opcode==OP_Function ){ + iMem = pExpr->iTable = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0); + pExpr->op = TK_REGISTER; + } +} +#endif + /* ** Generate code that pushes the value of every element of the given ** expression list onto the stack. @@ -1737,6 +1983,8 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){ /* ** Add a new element to the pParse->aAgg[] array and return its index. +** The new element is initialized to zero. The calling function is +** expected to fill it in. */ static int appendAggInfo(Parse *pParse){ if( (pParse->nAgg & 0x7)==0 ){ @@ -1751,81 +1999,92 @@ static int appendAggInfo(Parse *pParse){ return pParse->nAgg++; } +/* +** This is an xFunc for walkExprTree() used to implement +** sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates +** for additional information. +** +** This routine analyzes the aggregate function at pExpr. +*/ +static int analyzeAggregate(void *pArg, Expr *pExpr){ + int i; + AggExpr *aAgg; + NameContext *pNC = (NameContext *)pArg; + Parse *pParse = pNC->pParse; + SrcList *pSrcList = pNC->pSrcList; + + switch( pExpr->op ){ + case TK_COLUMN: { + for(i=0; pSrcList && inSrc; i++){ + if( pExpr->iTable==pSrcList->a[i].iCursor ){ + aAgg = pParse->aAgg; + for(i=0; inAgg; i++){ + if( aAgg[i].isAgg ) continue; + if( aAgg[i].pExpr->iTable==pExpr->iTable + && aAgg[i].pExpr->iColumn==pExpr->iColumn ){ + break; + } + } + if( i>=pParse->nAgg ){ + i = appendAggInfo(pParse); + if( i<0 ) return 1; + pParse->aAgg[i].isAgg = 0; + pParse->aAgg[i].pExpr = pExpr; + } + pExpr->iAgg = i; + pExpr->iAggCtx = pNC->nDepth; + return 1; + } + } + return 1; + } + case TK_AGG_FUNCTION: { + if( pNC->nDepth==0 ){ + aAgg = pParse->aAgg; + for(i=0; inAgg; i++){ + if( !aAgg[i].isAgg ) continue; + if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){ + break; + } + } + if( i>=pParse->nAgg ){ + u8 enc = pParse->db->enc; + i = appendAggInfo(pParse); + if( i<0 ) return 1; + pParse->aAgg[i].isAgg = 1; + pParse->aAgg[i].pExpr = pExpr; + pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db, + pExpr->token.z, pExpr->token.n, + pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); + } + pExpr->iAgg = i; + return 1; + } + } + } + if( pExpr->pSelect ){ + pNC->nDepth++; + walkSelectExpr(pExpr->pSelect, analyzeAggregate, pNC); + pNC->nDepth--; + } + return 0; +} + /* ** Analyze the given expression looking for aggregate functions and ** for variables that need to be added to the pParse->aAgg[] array. ** Make additional entries to the pParse->aAgg[] array as necessary. ** ** This routine should only be called after the expression has been -** analyzed by sqlite3ExprResolveIds() and sqlite3ExprCheck(). +** analyzed by sqlite3ExprResolveNames(). ** ** If errors are seen, leave an error message in zErrMsg and return ** the number of errors. */ -int sqlite3ExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){ - int i; - AggExpr *aAgg; - int nErr = 0; - - if( pExpr==0 ) return 0; - switch( pExpr->op ){ - case TK_COLUMN: { - aAgg = pParse->aAgg; - for(i=0; inAgg; i++){ - if( aAgg[i].isAgg ) continue; - if( aAgg[i].pExpr->iTable==pExpr->iTable - && aAgg[i].pExpr->iColumn==pExpr->iColumn ){ - break; - } - } - if( i>=pParse->nAgg ){ - i = appendAggInfo(pParse); - if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 0; - pParse->aAgg[i].pExpr = pExpr; - } - pExpr->iAgg = i; - break; - } - case TK_AGG_FUNCTION: { - aAgg = pParse->aAgg; - for(i=0; inAgg; i++){ - if( !aAgg[i].isAgg ) continue; - if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){ - break; - } - } - if( i>=pParse->nAgg ){ - u8 enc = pParse->db->enc; - i = appendAggInfo(pParse); - if( i<0 ) return 1; - pParse->aAgg[i].isAgg = 1; - pParse->aAgg[i].pExpr = pExpr; - pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db, - pExpr->token.z, pExpr->token.n, - pExpr->pList ? pExpr->pList->nExpr : 0, enc, 0); - } - pExpr->iAgg = i; - break; - } - default: { - if( pExpr->pLeft ){ - nErr = sqlite3ExprAnalyzeAggregates(pParse, pExpr->pLeft); - } - if( nErr==0 && pExpr->pRight ){ - nErr = sqlite3ExprAnalyzeAggregates(pParse, pExpr->pRight); - } - if( nErr==0 && pExpr->pList ){ - int n = pExpr->pList->nExpr; - int i; - for(i=0; nErr==0 && ipList->a[i].pExpr); - } - } - break; - } - } - return nErr; +int sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ + int nErr = pNC->pParse->nErr; + walkExprTree(pExpr, analyzeAggregate, pNC); + return pNC->pParse->nErr - nErr; } /* @@ -1917,7 +2176,10 @@ FuncDef *sqlite3FindFunction( pBest->iPrefEnc = enc; memcpy(pBest->zName, zName, nName); pBest->zName[nName] = 0; - sqlite3HashInsert(&db->aFunc, pBest->zName, nName, (void*)pBest); + if( pBest==sqlite3HashInsert(&db->aFunc,pBest->zName,nName,(void*)pBest) ){ + sqliteFree(pBest); + return 0; + } } if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){ diff --git a/db/sqlite3/src/func.c b/db/sqlite3/src/func.c index 46952284e6e..84bb3c2ac81 100644 --- a/db/sqlite3/src/func.c +++ b/db/sqlite3/src/func.c @@ -16,13 +16,13 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.85 2004/10/06 15:41:17 drh Exp $ +** $Id: func.c,v 1.96 2005/02/15 21:36:18 drh Exp $ */ +#include "sqliteInt.h" #include #include #include #include -#include "sqliteInt.h" #include "vdbeInt.h" #include "os.h" @@ -347,10 +347,11 @@ static const struct compareInfo likeInfo = { '%', '_', 0, 1 }; ** ** abc[*]xyz Matches "abc*xyz" only */ -int patternCompare( +static int patternCompare( const u8 *zPattern, /* The glob pattern */ const u8 *zString, /* The string to compare against the glob */ - const struct compareInfo *pInfo /* Information about how to do the compare */ + const struct compareInfo *pInfo, /* Information about how to do the compare */ + const int esc /* The escape character */ ){ register int c; int invert; @@ -360,9 +361,10 @@ int patternCompare( u8 matchAll = pInfo->matchAll; u8 matchSet = pInfo->matchSet; u8 noCase = pInfo->noCase; + int prevEscape = 0; /* True if the previous character was 'escape' */ while( (c = *zPattern)!=0 ){ - if( c==matchAll ){ + if( !prevEscape && c==matchAll ){ while( (c=zPattern[1]) == matchAll || c == matchOne ){ if( c==matchOne ){ if( *zString==0 ) return 0; @@ -370,9 +372,15 @@ int patternCompare( } zPattern++; } + if( c && esc && sqlite3ReadUtf8(&zPattern[1])==esc ){ + u8 const *zTemp = &zPattern[1]; + sqliteNextChar(zTemp); + c = *zTemp; + } if( c==0 ) return 1; if( c==matchSet ){ - while( *zString && patternCompare(&zPattern[1],zString,pInfo)==0 ){ + assert( esc==0 ); /* This is GLOB, not LIKE */ + while( *zString && patternCompare(&zPattern[1],zString,pInfo,esc)==0 ){ sqliteNextChar(zString); } return *zString!=0; @@ -386,17 +394,18 @@ int patternCompare( while( c2 != 0 && c2 != c ){ c2 = *++zString; } } if( c2==0 ) return 0; - if( patternCompare(&zPattern[1],zString,pInfo) ) return 1; + if( patternCompare(&zPattern[1],zString,pInfo,esc) ) return 1; sqliteNextChar(zString); } return 0; } - }else if( c==matchOne ){ + }else if( !prevEscape && c==matchOne ){ if( *zString==0 ) return 0; sqliteNextChar(zString); zPattern++; }else if( c==matchSet ){ int prior_c = 0; + assert( esc==0 ); /* This only occurs for GLOB, not LIKE */ seen = 0; invert = 0; c = sqliteCharVal(zString); @@ -424,6 +433,9 @@ int patternCompare( if( c2==0 || (seen ^ invert)==0 ) return 0; sqliteNextChar(zString); zPattern++; + }else if( esc && !prevEscape && sqlite3ReadUtf8(zPattern)==esc){ + prevEscape = 1; + sqliteNextChar(zPattern); }else{ if( noCase ){ if( sqlite3UpperToLower[c] != sqlite3UpperToLower[*zString] ) return 0; @@ -432,6 +444,7 @@ int patternCompare( } zPattern++; zString++; + prevEscape = 0; } } return *zString==0; @@ -457,8 +470,21 @@ static void likeFunc( ){ const unsigned char *zA = sqlite3_value_text(argv[0]); const unsigned char *zB = sqlite3_value_text(argv[1]); + int escape = 0; + if( argc==3 ){ + /* The escape character string must consist of a single UTF-8 character. + ** Otherwise, return an error. + */ + const unsigned char *zEsc = sqlite3_value_text(argv[2]); + if( sqlite3utf8CharLen(zEsc, -1)!=1 ){ + sqlite3_result_error(context, + "ESCAPE expression must be a single character", -1); + return; + } + escape = sqlite3ReadUtf8(zEsc); + } if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo)); + sqlite3_result_int(context, patternCompare(zA, zB, &likeInfo, escape)); } } @@ -469,13 +495,13 @@ static void likeFunc( ** ** A GLOB B ** -** is implemented as glob(A,B). +** is implemented as glob(B,A). */ static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){ const unsigned char *zA = sqlite3_value_text(argv[0]); const unsigned char *zB = sqlite3_value_text(argv[1]); if( zA && zB ){ - sqlite3_result_int(context, patternCompare(zA, zB, &globInfo)); + sqlite3_result_int(context, patternCompare(zA, zB, &globInfo, 0)); } } @@ -507,6 +533,7 @@ static void versionFunc( sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC); } + /* ** EXPERIMENTAL - This is not an official function. The interface may ** change. This function may disappear. Do not write code that depends @@ -704,10 +731,12 @@ static void test_destructor( memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len); if( db->enc==SQLITE_UTF8 ){ sqlite3_result_text(pCtx, zVal, -1, destructor); +#ifndef SQLITE_OMIT_UTF16 }else if( db->enc==SQLITE_UTF16LE ){ sqlite3_result_text16le(pCtx, zVal, -1, destructor); }else{ sqlite3_result_text16be(pCtx, zVal, -1, destructor); +#endif /* SQLITE_OMIT_UTF16 */ } } static void test_destructor_count( @@ -762,6 +791,20 @@ static void test_auxdata( } #endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST +/* +** A function to test error reporting from user functions. This function +** returns a copy of it's first argument as an error. +*/ +static void test_error( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **argv +){ + sqlite3_result_error(pCtx, sqlite3_value_text(argv[0]), 0); +} +#endif /* SQLITE_TEST */ + /* ** An instance of the following structure holds the context of a ** sum() or avg() aggregate computation. @@ -808,33 +851,6 @@ struct StdDevCtx { int cnt; /* Number of terms counted */ }; -#if 0 /* Omit because math library is required */ -/* -** Routines used to compute the standard deviation as an aggregate. -*/ -static void stdDevStep(sqlite3_context *context, int argc, const char **argv){ - StdDevCtx *p; - double x; - if( argc<1 ) return; - p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p && argv[0] ){ - x = sqlite3AtoF(argv[0], 0); - p->sum += x; - p->sum2 += x*x; - p->cnt++; - } -} -static void stdDevFinalize(sqlite3_context *context){ - double rN = sqlite3_aggregate_count(context); - StdDevCtx *p = sqlite3_aggregate_context(context, sizeof(*p)); - if( p && p->cnt>1 ){ - double rCnt = cnt; - sqlite3_set_result_double(context, - sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0))); - } -} -#endif - /* ** The following structure keeps track of state information for the ** count() aggregate function. @@ -933,7 +949,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc }, { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc }, { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc }, +#ifndef SQLITE_OMIT_UTF16 { "substr", 3, 0, SQLITE_UTF16LE, 0, sqlite3utf16Substr }, +#endif { "abs", 1, 0, SQLITE_UTF8, 0, absFunc }, { "round", 1, 0, SQLITE_UTF8, 0, roundFunc }, { "round", 2, 0, SQLITE_UTF8, 0, roundFunc }, @@ -945,6 +963,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc }, { "random", -1, 0, SQLITE_UTF8, 0, randomFunc }, { "like", 2, 0, SQLITE_UTF8, 0, likeFunc }, + { "like", 3, 0, SQLITE_UTF8, 0, likeFunc }, { "glob", 2, 0, SQLITE_UTF8, 0, globFunc }, { "nullif", 2, 0, SQLITE_UTF8, 1, nullifFunc }, { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc}, @@ -960,6 +979,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "test_destructor", 1, 1, SQLITE_UTF8, 0, test_destructor}, { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count}, { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata}, + { "test_error", 1, 0, SQLITE_UTF8, 0, test_error}, #endif }; static const struct { @@ -976,9 +996,6 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ { "avg", 1, 0, 0, sumStep, avgFinalize }, { "count", 0, 0, 0, countStep, countFinalize }, { "count", 1, 0, 0, countStep, countFinalize }, -#if 0 - { "stddev", 1, 0, stdDevStep, stdDevFinalize }, -#endif }; int i; @@ -998,6 +1015,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ } } } +#ifndef SQLITE_OMIT_ALTERTABLE + sqlite3AlterFunctions(db); +#endif for(i=0; i @@ -98,7 +98,14 @@ static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){ ** Hash and comparison functions when the mode is SQLITE_HASH_STRING */ static int strHash(const void *pKey, int nKey){ - return sqlite3HashNoCase((const char*)pKey, nKey); + const char *z = (const char *)pKey; + int h = 0; + if( nKey<=0 ) nKey = strlen(z); + while( nKey > 0 ){ + h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++]; + nKey--; + } + return h & 0x7fffffff; } static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){ if( n1!=n2 ) return 1; diff --git a/db/sqlite3/src/insert.c b/db/sqlite3/src/insert.c index 114942e8c4a..f96184da17e 100644 --- a/db/sqlite3/src/insert.c +++ b/db/sqlite3/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.119 2004/10/05 02:41:42 drh Exp $ +** $Id: insert.c,v 1.138 2005/03/21 01:20:58 drh Exp $ */ #include "sqliteInt.h" @@ -94,6 +94,27 @@ void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ sqlite3VdbeChangeP3(v, -1, pTab->zColAff, 0); } +/* +** Return non-zero if SELECT statement p opens the table with rootpage +** iTab in database iDb. This is used to see if a statement of the form +** "INSERT INTO SELECT ..." can run without using temporary +** table for the results of the SELECT. +** +** No checking is done for sub-selects that are part of expressions. +*/ +static int selectReadsTable(Select *p, int iDb, int iTab){ + int i; + struct SrcList_item *pItem; + if( p->pSrc==0 ) return 0; + for(i=0, pItem=p->pSrc->a; ipSrc->nSrc; i++, pItem++){ + if( pItem->pSelect ){ + if( selectReadsTable(pItem->pSelect, iDb, iTab) ) return 1; + }else{ + if( pItem->pTab->iDb==iDb && pItem->pTab->tnum==iTab ) return 1; + } + } + return 0; +} /* ** This routine is call to handle SQL of the following forms: @@ -182,18 +203,24 @@ void sqlite3Insert( sqlite3 *db; /* The main database structure */ int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */ int endOfLoop; /* Label for the end of the insertion loop */ - int useTempTable; /* Store SELECT results in intermediate table */ + int useTempTable = 0; /* Store SELECT results in intermediate table */ int srcTab = 0; /* Data comes from this temporary cursor if >=0 */ int iSelectLoop = 0; /* Address of code that implements the SELECT */ int iCleanup = 0; /* Address of the cleanup code */ int iInsertBlock = 0; /* Address of the subroutine used to insert data */ int iCntMem = 0; /* Memory cell used for the row counter */ - int isView; /* True if attempting to insert into a view */ + int newIdx = -1; /* Cursor for the NEW table */ + Db *pDb; /* The database containing table being inserted into */ + int counterMem = 0; /* Memory cell holding AUTOINCREMENT counter */ - int row_triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ - int before_triggers; /* True if there are BEFORE triggers */ - int after_triggers; /* True if there are AFTER triggers */ - int newIdx = -1; /* Cursor for the NEW table */ +#ifndef SQLITE_OMIT_TRIGGER + int isView; /* True if attempting to insert into a view */ + int triggers_exist = 0; /* True if there are FOR EACH ROW triggers */ +#endif + +#ifndef SQLITE_OMIT_AUTOINCREMENT + int counterRowid; /* Memory cell holding rowid of autoinc counter */ +#endif if( pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup; db = pParse->db; @@ -208,22 +235,32 @@ void sqlite3Insert( goto insert_cleanup; } assert( pTab->iDbnDb ); - zDb = db->aDb[pTab->iDb].zName; + pDb = &db->aDb[pTab->iDb]; + zDb = pDb->zName; if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){ goto insert_cleanup; } + /* Figure out if we have any triggers and if the table being + ** inserted into is a view + */ +#ifndef SQLITE_OMIT_TRIGGER + triggers_exist = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0); + isView = pTab->pSelect!=0; +#else +# define triggers_exist 0 +# define isView 0 +#endif +#ifdef SQLITE_OMIT_VIEW +# undef isView +# define isView 0 +#endif + /* Ensure that: * (a) the table is not read-only, * (b) that if it is a view then ON INSERT triggers exist */ - before_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT, - TK_BEFORE, TK_ROW, 0); - after_triggers = sqlite3TriggersExist(pParse, pTab->pTrigger, TK_INSERT, - TK_AFTER, TK_ROW, 0); - row_triggers_exist = before_triggers || after_triggers; - isView = pTab->pSelect!=0; - if( sqlite3IsReadOnly(pParse, pTab, before_triggers) ){ + if( sqlite3IsReadOnly(pParse, pTab, triggers_exist) ){ goto insert_cleanup; } if( pTab==0 ) goto insert_cleanup; @@ -245,14 +282,42 @@ void sqlite3Insert( */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; - sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || triggers_exist, pTab->iDb); /* if there are row triggers, allocate a temp table for new.* references. */ - if( row_triggers_exist ){ + if( triggers_exist ){ newIdx = pParse->nTab++; } +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* If this is an AUTOINCREMENT table, look up the sequence number in the + ** sqlite_sequence table and store it in memory cell counterMem. Also + ** remember the rowid of the sqlite_sequence table entry in memory cell + ** counterRowid. + */ + if( pTab->autoInc ){ + int iCur = pParse->nTab; + int base = sqlite3VdbeCurrentAddr(v); + counterRowid = pParse->nMem++; + counterMem = pParse->nMem++; + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pDb->pSeqTab->tnum); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2); + sqlite3VdbeAddOp(v, OP_Rewind, iCur, base+13); + sqlite3VdbeAddOp(v, OP_Column, iCur, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + sqlite3VdbeAddOp(v, OP_Ne, 28417, base+12); + sqlite3VdbeAddOp(v, OP_Recno, iCur, 0); + sqlite3VdbeAddOp(v, OP_MemStore, counterRowid, 1); + sqlite3VdbeAddOp(v, OP_Column, iCur, 1); + sqlite3VdbeAddOp(v, OP_MemStore, counterMem, 1); + sqlite3VdbeAddOp(v, OP_Goto, 0, base+13); + sqlite3VdbeAddOp(v, OP_Next, iCur, base+4); + sqlite3VdbeAddOp(v, OP_Close, iCur, 0); + } +#endif /* SQLITE_OMIT_AUTOINCREMENT */ + /* Figure out how many columns of data are supplied. If the data ** is coming from a SELECT statement, then this step also generates ** all the code to implement the SELECT statement and invoke a subroutine @@ -268,8 +333,11 @@ void sqlite3Insert( iInitCode = sqlite3VdbeAddOp(v, OP_Goto, 0, 0); iSelectLoop = sqlite3VdbeCurrentAddr(v); iInsertBlock = sqlite3VdbeMakeLabel(v); - rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0,0); + + /* Resolve the expressions in the SELECT statement and execute it. */ + rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0); if( rc || pParse->nErr || sqlite3_malloc_failed ) goto insert_cleanup; + iCleanup = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup); assert( pSelect->pEList ); @@ -283,20 +351,8 @@ void sqlite3Insert( ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ - if( row_triggers_exist ){ + if( triggers_exist || selectReadsTable(pSelect, pTab->iDb, pTab->tnum) ){ useTempTable = 1; - }else{ - int addr = 0; - useTempTable = 0; - while( useTempTable==0 ){ - VdbeOp *pOp; - addr = sqlite3VdbeFindOp(v, addr, OP_OpenRead, pTab->tnum); - if( addr==0 ) break; - pOp = sqlite3VdbeGetOp(v, addr-2); - if( pOp->opcode==OP_Integer && pOp->p1==pTab->iDb ){ - useTempTable = 1; - } - } } if( useTempTable ){ @@ -328,15 +384,16 @@ void sqlite3Insert( /* This is the case if the data for the INSERT is coming from a VALUES ** clause */ - SrcList dummy; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; assert( pList!=0 ); srcTab = -1; useTempTable = 0; assert( pList ); nColumn = pList->nExpr; - dummy.nSrc = 0; for(i=0; ia[i].pExpr,0,0) ){ + if( sqlite3ExprResolveNames(&sNC, pList->a[i].pExpr) ){ goto insert_cleanup; } } @@ -404,7 +461,7 @@ void sqlite3Insert( /* Open the temp table for FOR EACH ROW triggers */ - if( row_triggers_exist ){ + if( triggers_exist ){ sqlite3VdbeAddOp(v, OP_OpenPseudo, newIdx, 0); sqlite3VdbeAddOp(v, OP_SetNumColumns, newIdx, pTab->nCol); } @@ -418,7 +475,7 @@ void sqlite3Insert( } /* Open tables and indices if there are no row triggers */ - if( !row_triggers_exist ){ + if( !triggers_exist ){ base = pParse->nTab; sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); } @@ -440,7 +497,7 @@ void sqlite3Insert( /* Run the BEFORE and INSTEAD OF triggers, if there are any */ endOfLoop = sqlite3VdbeMakeLabel(v); - if( before_triggers ){ + if( triggers_exist & TRIGGER_BEFORE ){ /* build the NEW.* reference row. Note that if there is an INTEGER ** PRIMARY KEY into which a NULL is being inserted, that NULL will be @@ -452,9 +509,8 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_Integer, -1, 0); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, keyColumn); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1); }else{ + assert( pSelect==0 ); /* Otherwise useTempTable is true */ sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr); sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); @@ -473,13 +529,12 @@ void sqlite3Insert( } } if( pColumn && j>=pColumn->nId ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, j); - }else if( pSelect ){ - sqlite3VdbeAddOp(v, OP_Dup, nColumn-j-1, 1); }else{ - sqlite3ExprCode(pParse, pList->a[j].pExpr); + assert( pSelect==0 ); /* Otherwise useTempTable is true */ + sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr); } } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); @@ -495,7 +550,7 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); /* Fire BEFORE or INSTEAD OF triggers */ - if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab, + if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, newIdx, -1, onError, endOfLoop) ){ goto insert_cleanup; } @@ -504,7 +559,7 @@ void sqlite3Insert( /* If any triggers exists, the opening of tables and indices is deferred ** until now. */ - if( row_triggers_exist && !isView ){ + if( triggers_exist && !isView ){ base = pParse->nTab; sqlite3OpenTableAndIndices(pParse, pTab, base, OP_OpenWrite); } @@ -528,11 +583,16 @@ void sqlite3Insert( */ sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); - sqlite3VdbeAddOp(v, OP_NewRecno, base, 0); + sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); }else{ - sqlite3VdbeAddOp(v, OP_NewRecno, base, 0); + sqlite3VdbeAddOp(v, OP_NewRecno, base, counterMem); } +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( pTab->autoInc ){ + sqlite3VdbeAddOp(v, OP_MemMax, counterMem, 0); + } +#endif /* SQLITE_OMIT_AUTOINCREMENT */ /* Push onto the stack, data for all columns of the new entry, beginning ** with the first column. @@ -554,7 +614,7 @@ void sqlite3Insert( } } if( pColumn && j>=pColumn->nId ){ - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); }else if( useTempTable ){ sqlite3VdbeAddOp(v, OP_Column, srcTab, j); }else if( pSelect ){ @@ -570,7 +630,7 @@ void sqlite3Insert( sqlite3GenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0, 0, onError, endOfLoop); sqlite3CompleteInsertion(pParse, pTab, base, 0,0,0, - after_triggers ? newIdx : -1); + (triggers_exist & TRIGGER_AFTER)!=0 ? newIdx : -1); } /* Update the count of rows that are inserted @@ -579,7 +639,7 @@ void sqlite3Insert( sqlite3VdbeAddOp(v, OP_MemIncr, iCntMem, 0); } - if( row_triggers_exist ){ + if( triggers_exist ){ /* Close all tables opened */ if( !isView ){ sqlite3VdbeAddOp(v, OP_Close, base, 0); @@ -589,8 +649,8 @@ void sqlite3Insert( } /* Code AFTER triggers */ - if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1, - onError, endOfLoop) ){ + if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_AFTER, pTab, + newIdx, -1, onError, endOfLoop) ){ goto insert_cleanup; } } @@ -608,7 +668,7 @@ void sqlite3Insert( sqlite3VdbeResolveLabel(v, iCleanup); } - if( !row_triggers_exist ){ + if( !triggers_exist ){ /* Close all tables opened */ sqlite3VdbeAddOp(v, OP_Close, base, 0); for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){ @@ -616,10 +676,35 @@ void sqlite3Insert( } } - /* - ** Return the number of rows inserted. +#ifndef SQLITE_OMIT_AUTOINCREMENT + /* Update the sqlite_sequence table by storing the content of the + ** counter value in memory counterMem back into the sqlite_sequence + ** table. */ - if( db->flags & SQLITE_CountRows ){ + if( pTab->autoInc ){ + int iCur = pParse->nTab; + int base = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0); + sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pDb->pSeqTab->tnum); + sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, 2); + sqlite3VdbeAddOp(v, OP_MemLoad, counterRowid, 0); + sqlite3VdbeAddOp(v, OP_NotNull, -1, base+7); + sqlite3VdbeAddOp(v, OP_Pop, 1, 0); + sqlite3VdbeAddOp(v, OP_NewRecno, iCur, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->zName, 0); + sqlite3VdbeAddOp(v, OP_MemLoad, counterMem, 0); + sqlite3VdbeAddOp(v, OP_MakeRecord, 2, 0); + sqlite3VdbeAddOp(v, OP_PutIntKey, iCur, 0); + sqlite3VdbeAddOp(v, OP_Close, iCur, 0); + } +#endif + + /* + ** Return the number of rows inserted. If this routine is + ** generating code because of a call to sqlite3NestedParse(), do not + ** invoke the callback function. + */ + if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ sqlite3VdbeAddOp(v, OP_MemLoad, iCntMem, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeSetNumCols(v, 1); @@ -628,8 +713,8 @@ void sqlite3Insert( insert_cleanup: sqlite3SrcListDelete(pTabList); - if( pList ) sqlite3ExprListDelete(pList); - if( pSelect ) sqlite3SelectDelete(pSelect); + sqlite3ExprListDelete(pList); + sqlite3SelectDelete(pSelect); sqlite3IdListDelete(pColumn); } @@ -753,11 +838,13 @@ void sqlite3GenerateConstraintChecks( }else if( onError==OE_Default ){ onError = OE_Abort; } - if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){ + if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){ onError = OE_Abort; } sqlite3VdbeAddOp(v, OP_Dup, nCol-1-i, 1); addr = sqlite3VdbeAddOp(v, OP_NotNull, 1, 0); + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Rollback: case OE_Abort: @@ -775,11 +862,10 @@ void sqlite3GenerateConstraintChecks( break; } case OE_Replace: { - sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); sqlite3VdbeAddOp(v, OP_Push, nCol-i, 0); break; } - default: assert(0); } sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v)); } @@ -885,6 +971,8 @@ void sqlite3GenerateConstraintChecks( jumpInst2 = sqlite3VdbeAddOp(v, OP_IsUnique, base+iCur+1, 0); /* Generate code that executes if the new index entry is not unique */ + assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail + || onError==OE_Ignore || onError==OE_Replace ); switch( onError ){ case OE_Rollback: case OE_Abort: @@ -929,7 +1017,6 @@ void sqlite3GenerateConstraintChecks( seenReplace = 1; break; } - default: assert(0); } contAddr = sqlite3VdbeCurrentAddr(v); assert( contAddr<(1<<24) ); @@ -975,12 +1062,18 @@ void sqlite3CompleteInsertion( } sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0); sqlite3TableAffinityStr(v, pTab); +#ifndef SQLITE_OMIT_TRIGGER if( newIdx>=0 ){ sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_Dup, 1, 0); sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0); } - pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); +#endif + if( pParse->nested ){ + pik_flags = 0; + }else{ + pik_flags = (OPFLAG_NCHANGE|(isUpdate?0:OPFLAG_LASTROWID)); + } sqlite3VdbeAddOp(v, OP_PutIntKey, base, pik_flags); if( isUpdate && recnoChng ){ diff --git a/db/sqlite3/src/keywordhash.h b/db/sqlite3/src/keywordhash.h new file mode 100644 index 00000000000..b595541ff10 --- /dev/null +++ b/db/sqlite3/src/keywordhash.h @@ -0,0 +1,96 @@ +/* Hash score: 151 */ +static int keywordCode(const char *z, int n){ + static const char zText[510] = + "ABORTABLEFTEMPORARYADDATABASELECTHENDEFAULTRANSACTIONATURALTER" + "AISEACHECKEYAFTEREFERENCESCAPELSEXCEPTRIGGEREINDEXCLUSIVEXISTS" + "TATEMENTANDEFERRABLEXPLAINITIALLYATTACHAVINGLOBEFOREIGNORENAME" + "AUTOINCREMENTBEGINNEREPLACEBETWEENOTNULLIKEBYCASCADEFERREDELETE" + "CASECOLLATECOLUMNCOMMITCONFLICTCONSTRAINTERSECTCREATECROSSCURRENT_DATE" + "CURRENT_TIMESTAMPRAGMATCHDESCDETACHDISTINCTDROPRIMARYFAILIMIT" + "FROMFULLGROUPDATEIMMEDIATEINSERTINSTEADINTOFFSETISNULLJOINORDER" + "ESTRICTOUTERIGHTROLLBACKROWHENUNIONUNIQUEUSINGVACUUMVALUESVIEW" + "HERE"; + static const unsigned char aHash[127] = { + 89, 79, 101, 88, 0, 4, 0, 0, 108, 0, 75, 0, 0, + 92, 44, 0, 90, 0, 100, 103, 94, 0, 0, 10, 0, 0, + 107, 0, 104, 98, 0, 11, 47, 0, 41, 0, 0, 63, 69, + 0, 62, 19, 0, 0, 33, 81, 0, 102, 72, 0, 0, 30, + 0, 60, 34, 0, 8, 0, 109, 38, 12, 0, 76, 40, 25, + 64, 0, 0, 37, 80, 52, 36, 49, 20, 86, 0, 31, 0, + 73, 26, 0, 70, 0, 0, 0, 0, 46, 65, 22, 85, 35, + 67, 84, 0, 1, 0, 9, 51, 57, 18, 0, 106, 74, 96, + 53, 6, 83, 0, 0, 48, 91, 0, 99, 0, 68, 0, 0, + 15, 0, 110, 50, 55, 0, 2, 54, 0, 105, + }; + static const unsigned char aNext[110] = { + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, + 0, 0, 0, 5, 13, 0, 7, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, + 0, 16, 0, 23, 45, 0, 0, 0, 0, 28, 58, 0, 0, + 0, 0, 0, 0, 0, 0, 71, 42, 0, 0, 24, 59, 21, + 0, 78, 0, 66, 0, 0, 82, 29, 0, 0, 0, 0, 0, + 0, 0, 39, 93, 95, 0, 0, 97, 14, 27, 77, 0, 56, + 87, 0, 32, 0, 61, 0, + }; + static const unsigned char aLen[110] = { + 5, 5, 4, 4, 9, 2, 3, 8, 2, 6, 4, 3, 7, + 11, 2, 7, 5, 5, 4, 5, 3, 5, 10, 6, 4, 6, + 7, 7, 5, 9, 6, 9, 3, 10, 7, 9, 3, 6, 6, + 4, 6, 3, 7, 6, 6, 13, 2, 2, 5, 5, 7, 7, + 3, 7, 4, 4, 2, 7, 3, 8, 6, 4, 7, 6, 6, + 8, 10, 9, 6, 5, 12, 12, 17, 6, 5, 4, 6, 8, + 2, 4, 7, 4, 5, 4, 4, 5, 6, 9, 6, 7, 4, + 2, 6, 3, 6, 4, 5, 8, 5, 5, 8, 3, 4, 5, + 6, 5, 6, 6, 4, 5, + }; + static const unsigned short int aOffset[110] = { + 0, 4, 7, 10, 10, 14, 19, 21, 26, 27, 32, 34, 36, + 42, 51, 52, 57, 61, 65, 67, 71, 74, 78, 86, 91, 94, + 99, 105, 107, 110, 118, 123, 132, 134, 143, 148, 153, 157, 162, + 167, 170, 172, 172, 176, 180, 186, 188, 190, 199, 202, 206, 213, + 219, 219, 222, 225, 229, 231, 232, 236, 243, 249, 253, 260, 266, + 272, 280, 287, 296, 302, 307, 319, 319, 335, 339, 344, 348, 354, + 355, 362, 365, 372, 375, 380, 384, 388, 391, 397, 406, 412, 419, + 422, 422, 425, 428, 434, 438, 442, 450, 454, 459, 467, 469, 473, + 478, 484, 489, 495, 501, 504, + }; + static const unsigned char aCode[110] = { + TK_ABORT, TK_TABLE, TK_JOIN_KW, TK_TEMP, TK_TEMP, + TK_OR, TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, + TK_THEN, TK_END, TK_DEFAULT, TK_TRANSACTION,TK_ON, + TK_JOIN_KW, TK_ALTER, TK_RAISE, TK_EACH, TK_CHECK, + TK_KEY, TK_AFTER, TK_REFERENCES, TK_ESCAPE, TK_ELSE, + TK_EXCEPT, TK_TRIGGER, TK_REINDEX, TK_INDEX, TK_EXCLUSIVE, + TK_EXISTS, TK_STATEMENT, TK_AND, TK_DEFERRABLE, TK_EXPLAIN, + TK_INITIALLY, TK_ALL, TK_ATTACH, TK_HAVING, TK_GLOB, + TK_BEFORE, TK_FOR, TK_FOREIGN, TK_IGNORE, TK_RENAME, + TK_AUTOINCR, TK_TO, TK_IN, TK_BEGIN, TK_JOIN_KW, + TK_REPLACE, TK_BETWEEN, TK_NOT, TK_NOTNULL, TK_NULL, + TK_LIKE, TK_BY, TK_CASCADE, TK_ASC, TK_DEFERRED, + TK_DELETE, TK_CASE, TK_COLLATE, TK_COLUMNKW, TK_COMMIT, + TK_CONFLICT, TK_CONSTRAINT, TK_INTERSECT, TK_CREATE, TK_JOIN_KW, + TK_CDATE, TK_CTIME, TK_CTIMESTAMP, TK_PRAGMA, TK_MATCH, + TK_DESC, TK_DETACH, TK_DISTINCT, TK_IS, TK_DROP, + TK_PRIMARY, TK_FAIL, TK_LIMIT, TK_FROM, TK_JOIN_KW, + TK_GROUP, TK_UPDATE, TK_IMMEDIATE, TK_INSERT, TK_INSTEAD, + TK_INTO, TK_OF, TK_OFFSET, TK_SET, TK_ISNULL, + TK_JOIN, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, + TK_ROLLBACK, TK_ROW, TK_WHEN, TK_UNION, TK_UNIQUE, + TK_USING, TK_VACUUM, TK_VALUES, TK_VIEW, TK_WHERE, + }; + int h, i; + if( n<2 ) return TK_ID; + h = ((sqlite3UpperToLower[((unsigned char*)z)[0]]*4) ^ + (sqlite3UpperToLower[((unsigned char*)z)[n-1]]*3) ^ + n) % 127; + for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){ + if( aLen[i]==n && sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){ + return aCode[i]; + } + } + return TK_ID; +} +int sqlite3KeywordCode(const char *z, int n){ + return keywordCode(z, n); +} diff --git a/db/sqlite3/src/main.c b/db/sqlite3/src/main.c index dc17c224f91..dca52977c43 100644 --- a/db/sqlite3/src/main.c +++ b/db/sqlite3/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.263 2004/10/06 15:41:17 drh Exp $ +** $Id: main.c,v 1.283 2005/03/21 04:04:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -26,6 +26,16 @@ */ const int sqlite3one = 1; +#ifndef SQLITE_OMIT_GLOBALRECOVER +/* +** Linked list of all open database handles. This is used by the +** sqlite3_global_recover() function. Entries are added to the list +** by openDatabase() and removed by sqlite3_close(). +*/ +static sqlite3 *pDbList = 0; +#endif + + /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. @@ -202,7 +212,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** meta[2] Size of the page cache. ** meta[3] Use freelist if 0. Autovacuum if greater than zero. ** meta[4] Db text encoding. 1:UTF-8 3:UTF-16 LE 4:UTF-16 BE - ** meta[5] + ** meta[5] The user cookie. Used by the application. ** meta[6] ** meta[7] ** meta[8] @@ -257,12 +267,25 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ /* This happens if the database was initially empty */ db->file_format = 1; } + + if( db->file_format==2 || db->file_format==3 ){ + /* File format 2 is treated exactly as file format 1. New + ** databases are created with file format 1. + */ + db->file_format = 1; + } } /* - ** file_format==1 Version 3.0.0. + ** file_format==1 Version 3.0.0. + ** file_format==2 Version 3.1.3. + ** file_format==3 Version 3.1.4. + ** + ** Version 3.0 can only use files with file_format==1. Version 3.1.3 + ** can read and write files with file_format==1 or file_format==2. + ** Version 3.1.4 can read and write file formats 1, 2 and 3. */ - if( meta[1]>1 ){ + if( meta[1]>3 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; @@ -279,7 +302,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ }else{ char *zSql; zSql = sqlite3MPrintf( - "SELECT name, rootpage, sql, %s FROM '%q'.%s", + "SELECT name, rootpage, sql, '%s' FROM '%q'.%s", zDbNum, db->aDb[iDb].zName, zMasterName); sqlite3SafetyOff(db); rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); @@ -373,12 +396,13 @@ int sqlite3ReadSchema(Parse *pParse){ const char rcsid3[] = "@(#) \044Id: SQLite version " SQLITE_VERSION " $"; const char sqlite3_version[] = SQLITE_VERSION; const char *sqlite3_libversion(void){ return sqlite3_version; } +int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } /* ** This is the default collating function named "BINARY" which is always ** available. */ -static int binaryCollatingFunc( +static int binCollFunc( void *NotUsed, int nKey1, const void *pKey1, int nKey2, const void *pKey2 @@ -500,6 +524,23 @@ int sqlite3_close(sqlite3 *db){ sqlite3ValueFree(db->pErr); } +#ifndef SQLITE_OMIT_GLOBALRECOVER + { + sqlite3 *pPrev = pDbList; + sqlite3OsEnterMutex(); + while( pPrev && pPrev->pNext!=db ){ + pPrev = pPrev->pNext; + } + if( pPrev ){ + pPrev->pNext = db->pNext; + }else{ + assert( pDbList==db ); + pDbList = db->pNext; + } + sqlite3OsLeaveMutex(); + } +#endif + db->magic = SQLITE_MAGIC_ERROR; sqliteFree(db); return SQLITE_OK; @@ -553,7 +594,7 @@ const char *sqlite3ErrStr(int rc){ case SQLITE_NOLFS: z = "kernel lacks large file support"; break; case SQLITE_AUTH: z = "authorization denied"; break; case SQLITE_FORMAT: z = "auxiliary database format error"; break; - case SQLITE_RANGE: z = "bind index out of range"; break; + case SQLITE_RANGE: z = "bind or column index out of range"; break; case SQLITE_NOTADB: z = "file is encrypted or is not a database";break; default: z = "unknown error"; break; } @@ -706,6 +747,7 @@ int sqlite3_create_function( return SQLITE_ERROR; } +#ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. @@ -725,6 +767,25 @@ int sqlite3_create_function( if( rc!=SQLITE_OK ) return rc; enc = SQLITE_UTF16BE; } +#else + enc = SQLITE_UTF8; +#endif + + /* Check if an existing function is being overridden or deleted. If so, + ** and there are active VMs, then return SQLITE_BUSY. If a function + ** is being overridden/deleted but there are no active VMs, allow the + ** operation to continue but invalidate all precompiled statements. + */ + p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0); + if( p && p->iPrefEnc==enc && p->nArg==nArg ){ + if( db->activeVdbeCnt ){ + sqlite3Error(db, SQLITE_BUSY, + "Unable to delete/modify user-function due to active statements"); + return SQLITE_BUSY; + }else{ + sqlite3ExpirePreparedStatements(db); + } + } p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1); if( p==0 ) return SQLITE_NOMEM; @@ -734,6 +795,7 @@ int sqlite3_create_function( p->pUserData = pUserData; return SQLITE_OK; } +#ifndef SQLITE_OMIT_UTF16 int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, @@ -762,6 +824,7 @@ int sqlite3_create_function16( pUserData, xFunc, xStep, xFinal); return rc; } +#endif /* ** Register a trace function. The pArg from the previously registered trace @@ -835,13 +898,14 @@ int sqlite3BtreeFactory( if( omitJournal ){ btree_flags |= BTREE_OMIT_JOURNAL; } + if( db->flags & SQLITE_NoReadlock ){ + btree_flags |= BTREE_NO_READLOCK; + } if( zFilename==0 ){ -#ifndef TEMP_STORE -# define TEMP_STORE 1 -#endif #if TEMP_STORE==0 /* Do nothing */ #endif +#ifndef SQLITE_OMIT_MEMORYDB #if TEMP_STORE==1 if( db->temp_store==2 ) zFilename = ":memory:"; #endif @@ -851,6 +915,7 @@ int sqlite3BtreeFactory( #if TEMP_STORE==3 zFilename = ":memory:"; #endif +#endif /* SQLITE_OMIT_MEMORYDB */ } rc = sqlite3BtreeOpen(zFilename, ppBtree, btree_flags); @@ -880,6 +945,7 @@ const char *sqlite3_errmsg(sqlite3 *db){ return z; } +#ifndef SQLITE_OMIT_UTF16 /* ** Return UTF-16 encoded English language explanation of the most recent ** error. @@ -919,6 +985,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){ } return z; } +#endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. @@ -1005,6 +1072,7 @@ int sqlite3_prepare( if( pzTail ) *pzTail = sParse.zTail; rc = sParse.rc; +#ifndef SQLITE_OMIT_EXPLAIN if( rc==SQLITE_OK && sParse.pVdbe && sParse.explain ){ sqlite3VdbeSetNumCols(sParse.pVdbe, 5); sqlite3VdbeSetColName(sParse.pVdbe, 0, "addr", P3_STATIC); @@ -1013,6 +1081,7 @@ int sqlite3_prepare( sqlite3VdbeSetColName(sParse.pVdbe, 3, "p2", P3_STATIC); sqlite3VdbeSetColName(sParse.pVdbe, 4, "p3", P3_STATIC); } +#endif prepare_out: if( sqlite3SafetyOff(db) ){ @@ -1033,6 +1102,7 @@ prepare_out: return rc; } +#ifndef SQLITE_OMIT_UTF16 /* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ @@ -1076,6 +1146,7 @@ int sqlite3_prepare16( return rc; } +#endif /* SQLITE_OMIT_UTF16 */ /* ** This routine does the work of opening a database on behalf of @@ -1091,7 +1162,6 @@ static int openDatabase( ){ sqlite3 *db; int rc, i; - char *zErrMsg = 0; /* Allocate the sqlite data structure */ db = sqliteMalloc( sizeof(sqlite3) ); @@ -1102,7 +1172,7 @@ static int openDatabase( db->aDb = db->aDbStatic; db->enc = SQLITE_UTF8; db->autoCommit = 1; - /* db->flags |= SQLITE_ShortColNames; */ + db->flags |= SQLITE_ShortColNames; sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); for(i=0; inDb; i++){ @@ -1116,11 +1186,9 @@ static int openDatabase( ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ - sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binaryCollatingFunc); - sqlite3_create_collation(db, "BINARY", SQLITE_UTF16LE, 0,binaryCollatingFunc); - sqlite3_create_collation(db, "BINARY", SQLITE_UTF16BE, 0,binaryCollatingFunc); - db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0); - if( !db->pDfltColl ){ + if( sqlite3_create_collation(db, "BINARY", SQLITE_UTF8, 0,binCollFunc) || + sqlite3_create_collation(db, "BINARY", SQLITE_UTF16, 0,binCollFunc) || + !(db->pDfltColl = sqlite3FindCollSeq(db, db->enc, "BINARY", 6, 0)) ){ rc = db->errCode; assert( rc!=SQLITE_OK ); db->magic = SQLITE_MAGIC_CLOSED; @@ -1150,20 +1218,22 @@ static int openDatabase( ** is accessed. */ sqlite3RegisterBuiltinFunctions(db); - if( rc==SQLITE_OK ){ - sqlite3Error(db, SQLITE_OK, 0); - db->magic = SQLITE_MAGIC_OPEN; - }else{ - sqlite3Error(db, rc, "%s", zErrMsg, 0); - if( zErrMsg ) sqliteFree(zErrMsg); - db->magic = SQLITE_MAGIC_CLOSED; - } + sqlite3Error(db, SQLITE_OK, 0); + db->magic = SQLITE_MAGIC_OPEN; opendb_out: if( sqlite3_errcode(db)==SQLITE_OK && sqlite3_malloc_failed ){ sqlite3Error(db, SQLITE_NOMEM, 0); } *ppDb = db; +#ifndef SQLITE_OMIT_GLOBALRECOVER + if( db ){ + sqlite3OsEnterMutex(); + db->pNext = pDbList; + pDbList = db; + sqlite3OsLeaveMutex(); + } +#endif return sqlite3_errcode(db); } @@ -1177,6 +1247,7 @@ int sqlite3_open( return openDatabase(zFilename, ppDb); } +#ifndef SQLITE_OMIT_UTF16 /* ** Open a new database handle. */ @@ -1205,6 +1276,7 @@ int sqlite3_open16( return rc; } +#endif /* SQLITE_OMIT_UTF16 */ /* ** The following routine destroys a virtual machine that is created by @@ -1239,7 +1311,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){ rc = SQLITE_OK; }else{ rc = sqlite3VdbeReset((Vdbe*)pStmt); - sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0); + sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0, 0); } return rc; } @@ -1276,6 +1348,21 @@ int sqlite3_create_collation( ); return SQLITE_ERROR; } + + /* Check if this call is removing or replacing an existing collation + ** sequence. If so, and there are active VMs, return busy. If there + ** are no active VMs, invalidate any pre-compiled statements. + */ + pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0); + if( pColl && pColl->xCmp ){ + if( db->activeVdbeCnt ){ + sqlite3Error(db, SQLITE_BUSY, + "Unable to delete/modify collation sequence due to active statements"); + return SQLITE_BUSY; + } + sqlite3ExpirePreparedStatements(db); + } + pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1); if( 0==pColl ){ rc = SQLITE_NOMEM; @@ -1288,6 +1375,7 @@ int sqlite3_create_collation( return rc; } +#ifndef SQLITE_OMIT_UTF16 /* ** Register a new collation sequence with the database handle db. */ @@ -1308,6 +1396,7 @@ int sqlite3_create_collation16( zName8 = sqlite3ValueText(pTmp, SQLITE_UTF8); return sqlite3_create_collation(db, zName8, enc, pCtx, xCompare); } +#endif /* SQLITE_OMIT_UTF16 */ /* ** Register a collation sequence factory callback with the database handle @@ -1327,6 +1416,7 @@ int sqlite3_collation_needed( return SQLITE_OK; } +#ifndef SQLITE_OMIT_UTF16 /* ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. @@ -1344,3 +1434,40 @@ int sqlite3_collation_needed16( db->pCollNeededArg = pCollNeededArg; return SQLITE_OK; } +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_GLOBALRECOVER +/* +** This function is called to recover from a malloc failure that occured +** within SQLite. +** +** This function is *not* threadsafe. Calling this from within a threaded +** application when threads other than the caller have used SQLite is +** dangerous and will almost certainly result in malfunctions. +*/ +int sqlite3_global_recover(){ + int rc = SQLITE_OK; + + if( sqlite3_malloc_failed ){ + sqlite3 *db; + int i; + sqlite3_malloc_failed = 0; + for(db=pDbList; db; db=db->pNext ){ + sqlite3ExpirePreparedStatements(db); + for(i=0; inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt && (rc=sqlite3BtreeReset(pBt)) ){ + goto recover_out; + } + } + db->autoCommit = 1; + } + } + +recover_out: + if( rc!=SQLITE_OK ){ + sqlite3_malloc_failed = 1; + } + return rc; +} +#endif diff --git a/db/sqlite3/src/opcodes.c b/db/sqlite3/src/opcodes.c index 4bdfb04027c..734d1a5409e 100644 --- a/db/sqlite3/src/opcodes.c +++ b/db/sqlite3/src/opcodes.c @@ -1,128 +1,137 @@ /* Automatically generated. Do not edit */ -/* See the mkopcodec.h script for details. */ +/* See the mkopcodec.awk script for details. */ +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) const char *const sqlite3OpcodeNames[] = { "?", - "MemLoad", - "Column", - "SetCookie", - "MoveGt", - "AggFocus", - "RowKey", - "IdxRecno", - "AggNext", - "OpenWrite", - "If", - "PutStrKey", - "Pop", - "SortPut", - "CollSeq", - "OpenRead", - "SortReset", - "AutoCommit", - "Sort", - "ListRewind", - "IntegrityCk", - "Function", - "Noop", - "Return", - "Variable", - "String", - "ParseSchema", - "PutIntKey", - "AggFunc", - "Close", - "ListWrite", - "CreateIndex", - "IsUnique", - "IdxIsNull", - "NotFound", - "MustBeInt", - "Halt", - "IdxLT", - "AddImm", - "Statement", - "RowData", - "Push", - "KeyAsData", - "NotExists", - "OpenTemp", - "MemIncr", - "Gosub", - "AggSet", - "Integer", - "SortNext", - "Prev", - "CreateTable", - "Last", - "ResetCount", - "Callback", - "ContextPush", - "DropTrigger", - "DropIndex", - "Or", - "And", - "Not", - "FullKey", - "IdxGE", - "IdxDelete", - "IsNull", - "NotNull", - "Ne", - "Eq", - "Gt", - "Le", - "Lt", - "Ge", - "BitAnd", - "BitOr", - "ShiftLeft", - "ShiftRight", - "Add", - "Subtract", - "Multiply", - "Divide", - "Remainder", - "Concat", - "Negative", - "Vacuum", - "BitNot", - "String8", - "MoveLe", - "IfNot", - "DropTable", - "MakeRecord", - "Delete", - "ListRead", - "ListReset", - "Dup", - "Goto", - "Clear", - "IdxGT", - "MoveLt", - "VerifyCookie", - "Pull", - "SetNumColumns", - "AbsValue", - "Transaction", - "AggGet", - "ContextPop", - "Next", - "AggInit", - "Distinct", - "NewRecno", - "AggReset", - "Destroy", - "ReadCookie", - "ForceInt", - "IdxColumn", - "Recno", - "OpenPseudo", - "Blob", - "MemStore", - "Rewind", - "MoveGe", - "IdxPut", - "Found", - "Real", - "HexBlob", - "NullRow", + /* 1 */ "MemLoad", + /* 2 */ "Column", + /* 3 */ "SetCookie", + /* 4 */ "IfMemPos", + /* 5 */ "MoveGt", + /* 6 */ "AggFocus", + /* 7 */ "RowKey", + /* 8 */ "IdxRecno", + /* 9 */ "AggNext", + /* 10 */ "OpenWrite", + /* 11 */ "If", + /* 12 */ "PutStrKey", + /* 13 */ "Pop", + /* 14 */ "SortPut", + /* 15 */ "AggContextPush", + /* 16 */ "CollSeq", + /* 17 */ "OpenRead", + /* 18 */ "Expire", + /* 19 */ "SortReset", + /* 20 */ "AutoCommit", + /* 21 */ "Sort", + /* 22 */ "ListRewind", + /* 23 */ "IntegrityCk", + /* 24 */ "Function", + /* 25 */ "Noop", + /* 26 */ "Return", + /* 27 */ "Variable", + /* 28 */ "String", + /* 29 */ "ParseSchema", + /* 30 */ "PutIntKey", + /* 31 */ "AggFunc", + /* 32 */ "Close", + /* 33 */ "ListWrite", + /* 34 */ "CreateIndex", + /* 35 */ "IsUnique", + /* 36 */ "IdxIsNull", + /* 37 */ "NotFound", + /* 38 */ "MustBeInt", + /* 39 */ "Halt", + /* 40 */ "IdxLT", + /* 41 */ "AddImm", + /* 42 */ "Statement", + /* 43 */ "RowData", + /* 44 */ "MemMax", + /* 45 */ "Push", + /* 46 */ "KeyAsData", + /* 47 */ "NotExists", + /* 48 */ "OpenTemp", + /* 49 */ "MemIncr", + /* 50 */ "Gosub", + /* 51 */ "AggSet", + /* 52 */ "Integer", + /* 53 */ "SortNext", + /* 54 */ "Prev", + /* 55 */ "CreateTable", + /* 56 */ "Last", + /* 57 */ "ResetCount", + /* 58 */ "Callback", + /* 59 */ "ContextPush", + /* 60 */ "DropTrigger", + /* 61 */ "DropIndex", + /* 62 */ "FullKey", + /* 63 */ "IdxGE", + /* 64 */ "Or", + /* 65 */ "And", + /* 66 */ "Not", + /* 67 */ "IdxDelete", + /* 68 */ "Vacuum", + /* 69 */ "MoveLe", + /* 70 */ "IsNull", + /* 71 */ "NotNull", + /* 72 */ "Ne", + /* 73 */ "Eq", + /* 74 */ "Gt", + /* 75 */ "Le", + /* 76 */ "Lt", + /* 77 */ "Ge", + /* 78 */ "IfNot", + /* 79 */ "BitAnd", + /* 80 */ "BitOr", + /* 81 */ "ShiftLeft", + /* 82 */ "ShiftRight", + /* 83 */ "Add", + /* 84 */ "Subtract", + /* 85 */ "Multiply", + /* 86 */ "Divide", + /* 87 */ "Remainder", + /* 88 */ "Concat", + /* 89 */ "Negative", + /* 90 */ "DropTable", + /* 91 */ "BitNot", + /* 92 */ "String8", + /* 93 */ "MakeRecord", + /* 94 */ "Delete", + /* 95 */ "AggContextPop", + /* 96 */ "ListRead", + /* 97 */ "ListReset", + /* 98 */ "Dup", + /* 99 */ "Goto", + /* 100 */ "Clear", + /* 101 */ "IdxGT", + /* 102 */ "MoveLt", + /* 103 */ "VerifyCookie", + /* 104 */ "Pull", + /* 105 */ "SetNumColumns", + /* 106 */ "AbsValue", + /* 107 */ "Transaction", + /* 108 */ "AggGet", + /* 109 */ "ContextPop", + /* 110 */ "Next", + /* 111 */ "AggInit", + /* 112 */ "Distinct", + /* 113 */ "NewRecno", + /* 114 */ "AggReset", + /* 115 */ "Destroy", + /* 116 */ "ReadCookie", + /* 117 */ "ForceInt", + /* 118 */ "Recno", + /* 119 */ "OpenPseudo", + /* 120 */ "Blob", + /* 121 */ "MemStore", + /* 122 */ "Rewind", + /* 123 */ "MoveGe", + /* 124 */ "IdxPut", + /* 125 */ "Found", + /* 126 */ "NullRow", + /* 127 */ "NotUsed_127", + /* 128 */ "NotUsed_128", + /* 129 */ "NotUsed_129", + /* 130 */ "Real", + /* 131 */ "HexBlob", }; +#endif diff --git a/db/sqlite3/src/opcodes.h b/db/sqlite3/src/opcodes.h index 498ddd9f9dc..8be3dc7ea17 100644 --- a/db/sqlite3/src/opcodes.h +++ b/db/sqlite3/src/opcodes.h @@ -1,126 +1,135 @@ /* Automatically generated. Do not edit */ /* See the mkopcodeh.awk script for details */ -#define OP_MemLoad 1 -#define OP_HexBlob 123 -#define OP_Column 2 -#define OP_SetCookie 3 -#define OP_Real 122 -#define OP_MoveGt 4 -#define OP_Ge 71 -#define OP_AggFocus 5 -#define OP_RowKey 6 -#define OP_IdxRecno 7 -#define OP_AggNext 8 -#define OP_Eq 67 -#define OP_OpenWrite 9 -#define OP_NotNull 65 -#define OP_If 10 -#define OP_PutStrKey 11 -#define OP_String8 85 -#define OP_Pop 12 -#define OP_SortPut 13 -#define OP_CollSeq 14 -#define OP_OpenRead 15 -#define OP_SortReset 16 -#define OP_AutoCommit 17 -#define OP_Gt 68 -#define OP_Sort 18 -#define OP_ListRewind 19 -#define OP_IntegrityCk 20 -#define OP_Function 21 -#define OP_Subtract 77 -#define OP_And 59 -#define OP_Noop 22 -#define OP_Return 23 -#define OP_Remainder 80 -#define OP_Multiply 78 -#define OP_Variable 24 -#define OP_String 25 -#define OP_ParseSchema 26 -#define OP_PutIntKey 27 -#define OP_AggFunc 28 -#define OP_Close 29 -#define OP_ListWrite 30 -#define OP_CreateIndex 31 -#define OP_IsUnique 32 -#define OP_IdxIsNull 33 -#define OP_NotFound 34 -#define OP_MustBeInt 35 -#define OP_Halt 36 -#define OP_IdxLT 37 -#define OP_AddImm 38 -#define OP_Statement 39 -#define OP_RowData 40 -#define OP_Push 41 -#define OP_Or 58 -#define OP_KeyAsData 42 -#define OP_NotExists 43 -#define OP_OpenTemp 44 -#define OP_MemIncr 45 -#define OP_Gosub 46 -#define OP_Divide 79 -#define OP_AggSet 47 -#define OP_Integer 48 -#define OP_SortNext 49 -#define OP_Prev 50 -#define OP_Concat 81 -#define OP_BitAnd 72 -#define OP_CreateTable 51 -#define OP_Last 52 -#define OP_IsNull 64 -#define OP_ShiftRight 75 -#define OP_ResetCount 53 -#define OP_Callback 54 -#define OP_ContextPush 55 -#define OP_DropTrigger 56 -#define OP_DropIndex 57 -#define OP_FullKey 61 -#define OP_IdxGE 62 -#define OP_IdxDelete 63 -#define OP_Vacuum 83 -#define OP_MoveLe 86 -#define OP_IfNot 87 -#define OP_DropTable 88 -#define OP_MakeRecord 89 -#define OP_Delete 90 -#define OP_ListRead 91 -#define OP_ListReset 92 -#define OP_ShiftLeft 74 -#define OP_Dup 93 -#define OP_Goto 94 -#define OP_Clear 95 -#define OP_IdxGT 96 -#define OP_MoveLt 97 -#define OP_Le 69 -#define OP_VerifyCookie 98 -#define OP_Pull 99 -#define OP_Not 60 -#define OP_SetNumColumns 100 -#define OP_AbsValue 101 -#define OP_Transaction 102 -#define OP_Negative 82 -#define OP_Ne 66 -#define OP_AggGet 103 -#define OP_ContextPop 104 -#define OP_BitOr 73 -#define OP_Next 105 -#define OP_AggInit 106 -#define OP_Distinct 107 -#define OP_NewRecno 108 -#define OP_Lt 70 -#define OP_AggReset 109 -#define OP_Destroy 110 -#define OP_ReadCookie 111 -#define OP_ForceInt 112 -#define OP_IdxColumn 113 -#define OP_Recno 114 -#define OP_OpenPseudo 115 -#define OP_Blob 116 -#define OP_Add 76 -#define OP_MemStore 117 -#define OP_Rewind 118 -#define OP_MoveGe 119 -#define OP_IdxPut 120 -#define OP_BitNot 84 -#define OP_Found 121 -#define OP_NullRow 124 +#define OP_MemLoad 1 +#define OP_HexBlob 131 /* same as TK_BLOB */ +#define OP_Column 2 +#define OP_SetCookie 3 +#define OP_IfMemPos 4 +#define OP_Real 130 /* same as TK_FLOAT */ +#define OP_MoveGt 5 +#define OP_Ge 77 /* same as TK_GE */ +#define OP_AggFocus 6 +#define OP_RowKey 7 +#define OP_IdxRecno 8 +#define OP_AggNext 9 +#define OP_Eq 73 /* same as TK_EQ */ +#define OP_OpenWrite 10 +#define OP_NotNull 71 /* same as TK_NOTNULL */ +#define OP_If 11 +#define OP_PutStrKey 12 +#define OP_String8 92 /* same as TK_STRING */ +#define OP_Pop 13 +#define OP_SortPut 14 +#define OP_AggContextPush 15 +#define OP_CollSeq 16 +#define OP_OpenRead 17 +#define OP_Expire 18 +#define OP_SortReset 19 +#define OP_AutoCommit 20 +#define OP_Gt 74 /* same as TK_GT */ +#define OP_Sort 21 +#define OP_ListRewind 22 +#define OP_IntegrityCk 23 +#define OP_Function 24 +#define OP_Subtract 84 /* same as TK_MINUS */ +#define OP_And 65 /* same as TK_AND */ +#define OP_Noop 25 +#define OP_Return 26 +#define OP_Remainder 87 /* same as TK_REM */ +#define OP_Multiply 85 /* same as TK_STAR */ +#define OP_Variable 27 +#define OP_String 28 +#define OP_ParseSchema 29 +#define OP_PutIntKey 30 +#define OP_AggFunc 31 +#define OP_Close 32 +#define OP_ListWrite 33 +#define OP_CreateIndex 34 +#define OP_IsUnique 35 +#define OP_IdxIsNull 36 +#define OP_NotFound 37 +#define OP_MustBeInt 38 +#define OP_Halt 39 +#define OP_IdxLT 40 +#define OP_AddImm 41 +#define OP_Statement 42 +#define OP_RowData 43 +#define OP_MemMax 44 +#define OP_Push 45 +#define OP_Or 64 /* same as TK_OR */ +#define OP_KeyAsData 46 +#define OP_NotExists 47 +#define OP_OpenTemp 48 +#define OP_MemIncr 49 +#define OP_Gosub 50 +#define OP_Divide 86 /* same as TK_SLASH */ +#define OP_AggSet 51 +#define OP_Integer 52 +#define OP_SortNext 53 +#define OP_Prev 54 +#define OP_Concat 88 /* same as TK_CONCAT */ +#define OP_BitAnd 79 /* same as TK_BITAND */ +#define OP_CreateTable 55 +#define OP_Last 56 +#define OP_IsNull 70 /* same as TK_ISNULL */ +#define OP_ShiftRight 82 /* same as TK_RSHIFT */ +#define OP_ResetCount 57 +#define OP_Callback 58 +#define OP_ContextPush 59 +#define OP_DropTrigger 60 +#define OP_DropIndex 61 +#define OP_FullKey 62 +#define OP_IdxGE 63 +#define OP_IdxDelete 67 +#define OP_Vacuum 68 +#define OP_MoveLe 69 +#define OP_IfNot 78 +#define OP_DropTable 90 +#define OP_MakeRecord 93 +#define OP_Delete 94 +#define OP_AggContextPop 95 +#define OP_ListRead 96 +#define OP_ListReset 97 +#define OP_ShiftLeft 81 /* same as TK_LSHIFT */ +#define OP_Dup 98 +#define OP_Goto 99 +#define OP_Clear 100 +#define OP_IdxGT 101 +#define OP_MoveLt 102 +#define OP_Le 75 /* same as TK_LE */ +#define OP_VerifyCookie 103 +#define OP_Pull 104 +#define OP_Not 66 /* same as TK_NOT */ +#define OP_SetNumColumns 105 +#define OP_AbsValue 106 +#define OP_Transaction 107 +#define OP_Negative 89 /* same as TK_UMINUS */ +#define OP_Ne 72 /* same as TK_NE */ +#define OP_AggGet 108 +#define OP_ContextPop 109 +#define OP_BitOr 80 /* same as TK_BITOR */ +#define OP_Next 110 +#define OP_AggInit 111 +#define OP_Distinct 112 +#define OP_NewRecno 113 +#define OP_Lt 76 /* same as TK_LT */ +#define OP_AggReset 114 +#define OP_Destroy 115 +#define OP_ReadCookie 116 +#define OP_ForceInt 117 +#define OP_Recno 118 +#define OP_OpenPseudo 119 +#define OP_Blob 120 +#define OP_Add 83 /* same as TK_PLUS */ +#define OP_MemStore 121 +#define OP_Rewind 122 +#define OP_MoveGe 123 +#define OP_IdxPut 124 +#define OP_BitNot 91 /* same as TK_BITNOT */ +#define OP_Found 125 +#define OP_NullRow 126 + +/* The following opcode values are never used */ +#define OP_NotUsed_127 127 +#define OP_NotUsed_128 128 +#define OP_NotUsed_129 129 diff --git a/db/sqlite3/src/os.h b/db/sqlite3/src/os.h index fc478baa93e..1f82a1fbf15 100644 --- a/db/sqlite3/src/os.h +++ b/db/sqlite3/src/os.h @@ -25,30 +25,17 @@ */ #if !defined(OS_UNIX) && !defined(OS_TEST) # ifndef OS_WIN -# ifndef OS_MAC -# if defined(__MACOS__) -# define OS_MAC 1 -# define OS_WIN 0 -# define OS_UNIX 0 -# elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) -# define OS_MAC 0 -# define OS_WIN 1 -# define OS_UNIX 0 -# else -# define OS_MAC 0 -# define OS_WIN 0 -# define OS_UNIX 1 -# endif -# else -# define OS_WIN 0 -# define OS_UNIX 0 +# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) +# define OS_WIN 1 +# define OS_UNIX 0 +# else +# define OS_WIN 0 +# define OS_UNIX 1 # endif # else -# define OS_MAC 0 # define OS_UNIX 0 # endif #else -# define OS_MAC 0 # ifndef OS_WIN # define OS_WIN 0 # endif @@ -66,8 +53,12 @@ #if OS_WIN # include "os_win.h" #endif -#if OS_MAC -# include "os_mac.h" + +/* If the SET_FULLSYNC macro is not defined above, then make it +** a no-op +*/ +#ifndef SET_FULLSYNC +# define SET_FULLSYNC(x,y) #endif /* @@ -162,7 +153,7 @@ ** */ #define PENDING_BYTE 0x40000000 /* First byte past the 1GB boundary */ -/* #define PENDING_BYTE 0x5400 // Page 20 - for testing */ +/* #define PENDING_BYTE 0x5400 // Page 22 - for testing */ #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 @@ -176,6 +167,7 @@ int sqlite3OsOpenReadOnly(const char*, OsFile*); int sqlite3OsOpenDirectory(const char*, OsFile*); int sqlite3OsSyncDirectory(const char*); int sqlite3OsTempFileName(char*); +int sqlite3OsIsDirWritable(char*); int sqlite3OsClose(OsFile*); int sqlite3OsRead(OsFile*, void*, int amt); int sqlite3OsWrite(OsFile*, const void*, int amt); diff --git a/db/sqlite3/src/os_unix.c b/db/sqlite3/src/os_unix.c index 94fca70199a..83de58f030a 100644 --- a/db/sqlite3/src/os_unix.c +++ b/db/sqlite3/src/os_unix.c @@ -574,7 +574,7 @@ int sqlite3OsOpenDirectory( ** name of a directory, then that directory will be used to store ** temporary files. */ -const char *sqlite3_temp_directory = 0; +char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to @@ -616,6 +616,22 @@ int sqlite3OsTempFileName(char *zBuf){ return SQLITE_OK; } +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Check that a given pathname is a directory and is writable +** +*/ +int sqlite3OsIsDirWritable(char *zBuf){ + struct stat buf; + if( zBuf==0 ) return 0; + if( zBuf[0]==0 ) return 0; + if( stat(zBuf, &buf) ) return 0; + if( !S_ISDIR(buf.st_mode) ) return 0; + if( access(zBuf, 07) ) return 0; + return 1; +} +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + /* ** Read data from a file into a buffer. Return SQLITE_OK if all ** bytes were read successfully and SQLITE_IOERR if anything goes @@ -628,7 +644,7 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ TIMER_START; got = read(id->h, pBuf, amt); TIMER_END; - TRACE4("READ %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED); + TRACE5("READ %-3d %5d %7d %d\n", id->h, got, last_page, TIMER_ELAPSED); SEEK(0); /* if( got<0 ) got = 0; */ if( got==amt ){ @@ -645,6 +661,7 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ int wrote = 0; assert( id->isOpen ); + assert( amt>0 ); SimulateIOError(SQLITE_IOERR); SimulateDiskfullError; TIMER_START; @@ -653,7 +670,7 @@ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ pBuf = &((char*)pBuf)[wrote]; } TIMER_END; - TRACE4("WRITE %-3d %7d %d\n", id->h, last_page, TIMER_ELAPSED); + TRACE5("WRITE %-3d %5d %7d %d\n", id->h, wrote, last_page, TIMER_ELAPSED); SEEK(0); if( amt>0 ){ return SQLITE_FULL; @@ -671,19 +688,60 @@ int sqlite3OsSeek(OsFile *id, i64 offset){ return SQLITE_OK; } +#ifdef SQLITE_TEST +/* +** Count the number of fullsyncs and normal syncs. This is used to test +** that syncs and fullsyncs are occuring at the right times. +*/ +int sqlite3_sync_count = 0; +int sqlite3_fullsync_count = 0; +#endif + + /* ** The fsync() system call does not work as advertised on many ** unix systems. The following procedure is an attempt to make ** it work better. +** +** The SQLITE_NO_SYNC macro disables all fsync()s. This is useful +** for testing when we want to run through the test suite quickly. +** You are strongly advised *not* to deploy with SQLITE_NO_SYNC +** enabled, however, since with SQLITE_NO_SYNC enabled, an OS crash +** or power failure will likely corrupt the database file. */ -static int full_fsync(int fd){ +static int full_fsync(int fd, int fullSync){ int rc; + + /* Record the number of times that we do a normal fsync() and + ** FULLSYNC. This is used during testing to verify that this procedure + ** gets called with the correct arguments. + */ +#ifdef SQLITE_TEST + if( fullSync ) sqlite3_fullsync_count++; + sqlite3_sync_count++; +#endif + + /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a + ** no-op + */ +#ifdef SQLITE_NO_SYNC + rc = SQLITE_OK; +#else + #ifdef F_FULLFSYNC - rc = fcntl(fd, F_FULLFSYNC, 0); + if( fullSync ){ + rc = fcntl(fd, F_FULLFSYNC, 0); + }else{ + rc = 1; + } + /* If the FULLSYNC failed, try to do a normal fsync() */ if( rc ) rc = fsync(fd); + #else rc = fsync(fd); -#endif +#endif /* defined(F_FULLFSYNC) */ +#endif /* defined(SQLITE_NO_SYNC) */ + return rc; } @@ -702,12 +760,12 @@ int sqlite3OsSync(OsFile *id){ assert( id->isOpen ); SimulateIOError(SQLITE_IOERR); TRACE2("SYNC %-3d\n", id->h); - if( full_fsync(id->h) ){ + if( full_fsync(id->h, id->fullSync) ){ return SQLITE_IOERR; } if( id->dirfd>=0 ){ TRACE2("DIRSYNC %-3d\n", id->dirfd); - full_fsync(id->dirfd); + full_fsync(id->dirfd, id->fullSync); close(id->dirfd); /* Only need to sync once, so close the directory */ id->dirfd = -1; /* when we are done. */ } @@ -717,6 +775,10 @@ int sqlite3OsSync(OsFile *id){ /* ** Sync the directory zDirname. This is a no-op on operating systems other ** than UNIX. +** +** This is used to make sure the master journal file has truely been deleted +** before making changes to individual journals on a multi-database commit. +** The F_FULLFSYNC option is not needed here. */ int sqlite3OsSyncDirectory(const char *zDirname){ int fd; @@ -879,7 +941,7 @@ int sqlite3OsLock(OsFile *id, int locktype){ int s; assert( id->isOpen ); - TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), + TRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", id->h, locktypeName(locktype), locktypeName(id->locktype), locktypeName(pLock->locktype), pLock->cnt ,getpid() ); @@ -888,7 +950,7 @@ int sqlite3OsLock(OsFile *id, int locktype){ ** sqlite3OsEnterMutex() hasn't been called yet. */ if( id->locktype>=locktype ){ - TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype)); + TRACE3("LOCK %d %s ok (already held)\n", id->h, locktypeName(locktype)); return SQLITE_OK; } @@ -1009,7 +1071,7 @@ int sqlite3OsLock(OsFile *id, int locktype){ end_lock: sqlite3OsLeaveMutex(); - TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype), + TRACE4("LOCK %d %s %s\n", id->h, locktypeName(locktype), rc==SQLITE_OK ? "ok" : "failed"); return rc; } @@ -1031,7 +1093,7 @@ int sqlite3OsUnlock(OsFile *id, int locktype){ int rc = SQLITE_OK; assert( id->isOpen ); - TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, + TRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", id->h, locktype, id->locktype, id->pLock->locktype, id->pLock->cnt, getpid()); assert( locktype<=SHARED_LOCK ); @@ -1157,10 +1219,16 @@ int sqlite3OsRandomSeed(char *zBuf){ memset(zBuf, 0, 256); #if !defined(SQLITE_TEST) { - int pid; - time((time_t*)zBuf); - pid = getpid(); - memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); + int pid, fd; + fd = open("/dev/urandom", O_RDONLY); + if( fd<0 ){ + time((time_t*)zBuf); + pid = getpid(); + memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid)); + }else{ + read(fd, zBuf, 256); + close(fd); + } } #endif return SQLITE_OK; diff --git a/db/sqlite3/src/os_unix.h b/db/sqlite3/src/os_unix.h index 72f818befee..72089625553 100644 --- a/db/sqlite3/src/os_unix.h +++ b/db/sqlite3/src/os_unix.h @@ -68,9 +68,15 @@ struct OsFile { int h; /* The file descriptor */ unsigned char locktype; /* The type of lock held on this fd */ unsigned char isOpen; /* True if needs to be closed */ + unsigned char fullSync; /* Use F_FULLSYNC if available */ int dirfd; /* File descriptor for the directory */ }; +/* +** A macro to set the OsFile.fullSync flag, if it exists. +*/ +#define SET_FULLSYNC(x,y) ((x).fullSync = (y)) + /* ** Maximum number of characters in a temporary file name */ diff --git a/db/sqlite3/src/os_win.c b/db/sqlite3/src/os_win.c index f6e3e3ea83b..6e51947afa6 100644 --- a/db/sqlite3/src/os_win.c +++ b/db/sqlite3/src/os_win.c @@ -18,6 +18,10 @@ #include +#ifdef __CYGWIN__ +# include +#endif + /* ** Macros used to determine whether or not to use threads. */ @@ -202,7 +206,7 @@ int sqlite3OsOpenDirectory( ** name of a directory, then that directory will be used to store ** temporary files. */ -const char *sqlite3_temp_directory = 0; +char *sqlite3_temp_directory = 0; /* ** Create a temporary file name in zBuf. zBuf must be big enough to @@ -275,12 +279,13 @@ int sqlite3OsRead(OsFile *id, void *pBuf, int amt){ ** or some other error code on failure. */ int sqlite3OsWrite(OsFile *id, const void *pBuf, int amt){ - int rc; + int rc = 0; DWORD wrote; assert( id->isOpen ); SimulateIOError(SQLITE_IOERR); SimulateDiskfullError; TRACE3("WRITE %d lock=%d\n", id->h, id->locktype); + assert( amt>0 ); while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){ amt -= wrote; pBuf = &((char*)pBuf)[wrote]; @@ -409,6 +414,24 @@ static int unlockReadLock(OsFile *id){ return res; } +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** Check that a given pathname is a directory and is writable +** +*/ +int sqlite3OsIsDirWritable(char *zBuf){ + int fileAttr; + if(! zBuf ) return 0; + if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0; + fileAttr = GetFileAttributesA(zBuf); + if( fileAttr == 0xffffffff ) return 0; + if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){ + return 0; + } + return 1; +} +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: @@ -684,10 +707,17 @@ char *sqlite3OsFullPathname(const char *zRelative){ char *zNotUsed; char *zFull; int nByte; +#ifdef __CYGWIN__ + nByte = strlen(zRelative) + MAX_PATH + 1001; + zFull = sqliteMalloc( nByte ); + if( zFull==0 ) return 0; + if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0; +#else nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1; zFull = sqliteMalloc( nByte ); if( zFull==0 ) return 0; GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed); +#endif return zFull; } diff --git a/db/sqlite3/src/pager.c b/db/sqlite3/src/pager.c index cf0da5200d6..9c6040a6285 100644 --- a/db/sqlite3/src/pager.c +++ b/db/sqlite3/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.167 2004/10/05 02:41:43 drh Exp $ +** @(#) $Id: pager.c,v 1.198 2005/03/21 04:04:02 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -34,13 +34,32 @@ #define TRACE2(X,Y) sqlite3DebugPrintf(X,Y) #define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z) #define TRACE4(X,Y,Z,W) sqlite3DebugPrintf(X,Y,Z,W) +#define TRACE5(X,Y,Z,W,V) sqlite3DebugPrintf(X,Y,Z,W,V) #else #define TRACE1(X) #define TRACE2(X,Y) #define TRACE3(X,Y,Z) #define TRACE4(X,Y,Z,W) +#define TRACE5(X,Y,Z,W,V) #endif +/* +** The following two macros are used within the TRACEX() macros above +** to print out file-descriptors. They are required so that tracing +** can be turned on when using both the regular os_unix.c and os_test.c +** backends. +** +** PAGERID() takes a pointer to a Pager struct as it's argument. The +** associated file-descriptor is returned. FILEHANDLEID() takes an OsFile +** struct as it's argument. +*/ +#ifdef OS_TEST +#define PAGERID(p) (p->fd->fd.h) +#define FILEHANDLEID(fd) (fd->fd.h) +#else +#define PAGERID(p) (p->fd.h) +#define FILEHANDLEID(fd) (fd.h) +#endif /* ** The page cache as a whole is always in one of the following @@ -110,6 +129,12 @@ # define SQLITE_BUSY_RESERVED_LOCK 0 #endif +/* +** This macro rounds values up so that if the value is an address it +** is guaranteed to be an address that is aligned to an 8-byte boundary. +*/ +#define FORCE_ALIGNMENT(X) (((X)+7)&~7) + /* ** Each in-memory image of a page begins with the following header. ** This header is only visible to this pager module. The client @@ -143,7 +168,10 @@ struct PgHdr { u8 alwaysRollback; /* Disable dont_rollback() for this page */ short int nRef; /* Number of users of this page */ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */ - /* pPager->pageSize bytes of page data follow this header */ +#ifdef SQLITE_CHECK_PAGES + u32 pageHash; +#endif + /* pPager->psAligned bytes of page data follow this header */ /* Pager.nExtra bytes of local data follow the page data */ }; @@ -179,9 +207,9 @@ struct PgHistory { */ #define PGHDR_TO_DATA(P) ((void*)(&(P)[1])) #define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1]) -#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->pageSize]) +#define PGHDR_TO_EXTRA(G,P) ((void*)&((char*)(&(G)[1]))[(P)->psAligned]) #define PGHDR_TO_HIST(P,PGR) \ - ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->pageSize+(PGR)->nExtra]) + ((PgHistory*)&((char*)(&(P)[1]))[(PGR)->psAligned+(PGR)->nExtra]) /* ** How big to make the hash table used for locating in-memory pages @@ -214,15 +242,19 @@ struct Pager { void (*xDestructor)(void*,int); /* Call this routine when freeing pages */ void (*xReiniter)(void*,int); /* Call this routine when reloading pages */ int pageSize; /* Number of bytes in a page */ + int psAligned; /* pageSize rounded up to a multiple of 8 */ int nPage; /* Total number of in-memory pages */ + int nMaxPage; /* High water mark of nPage */ int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */ int mxPage; /* Maximum number of pages to hold in cache */ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */ + int nRead,nWrite; /* Database pages read/written */ void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ void *pCodecArg; /* First argument to xCodec() */ u8 journalOpen; /* True if journal file descriptors is valid */ u8 journalStarted; /* True if header of journal is synced */ u8 useJournal; /* Use a rollback journal on this file */ + u8 noReadlock; /* Do not bother to obtain readlocks */ u8 stmtOpen; /* True if the statement subjournal is open */ u8 stmtInUse; /* True we are in a statement subtransaction */ u8 stmtAutoopen; /* Open stmt journal when main journal is opened*/ @@ -301,6 +333,21 @@ static const unsigned char aJournalMagic[] = { */ #define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) +/* +** The macro MEMDB is true if we are dealing with an in-memory database. +** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set, +** the value of MEMDB will be a constant and the compiler will optimize +** out code that would never execute. +*/ +#ifdef SQLITE_OMIT_MEMORYDB +# define MEMDB 0 +#else +# define MEMDB pPager->memDb +#endif + +/* +** The default size of a disk sector +*/ #define PAGER_SECTOR_SIZE 512 /* @@ -310,12 +357,18 @@ static const unsigned char aJournalMagic[] = { ** is devoted to storing a master journal name - there are no more pages to ** roll back. See comments for function writeMasterJournal() for details. */ -#define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) +/* #define PAGER_MJ_PGNO(x) (PENDING_BYTE/((x)->pageSize)) */ +#define PAGER_MJ_PGNO(x) ((PENDING_BYTE/((x)->pageSize))+1) + +/* +** The maximum legal page number is (2^31 - 1). +*/ +#define PAGER_MAX_PGNO 2147483647 /* ** Enable reference count tracking (for debugging) here: */ -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG int pager3_refinfo_enable = 0; static void pager_refinfo(PgHdr *p){ static int cnt = 0; @@ -402,6 +455,36 @@ static int pager_errcode(Pager *pPager){ return rc; } +#ifdef SQLITE_CHECK_PAGES +/* +** Return a 32-bit hash of the page data for pPage. +*/ +static u32 pager_pagehash(PgHdr *pPage){ + u32 hash = 0; + int i; + unsigned char *pData = (unsigned char *)PGHDR_TO_DATA(pPage); + for(i=0; ipPager->pageSize; i++){ + hash = (hash+i)^pData[i]; + } + return hash; +} + +/* +** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES +** is defined, and NDEBUG is not defined, an assert() statement checks +** that the page is either dirty or still matches the calculated page-hash. +*/ +#define CHECK_PAGE(x) checkPage(x) +static void checkPage(PgHdr *pPg){ + Pager *pPager = pPg->pPager; + assert( !pPg->pageHash || pPager->errMask || MEMDB || pPg->dirty || + pPg->pageHash==pager_pagehash(pPg) ); +} + +#else +#define CHECK_PAGE(x) +#endif + /* ** When this is called the journal file for pager pPager must be open. ** The master journal file name is read from the end of the file and @@ -463,8 +546,9 @@ static int readMasterJournal(OsFile *pJrnl, char **pzMaster){ */ sqliteFree(*pzMaster); *pzMaster = 0; + }else{ + (*pzMaster)[len] = '\0'; } - (*pzMaster)[len] = '\0'; return SQLITE_OK; } @@ -739,6 +823,7 @@ static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){ */ static void pager_reset(Pager *pPager){ PgHdr *pPg, *pNext; + if( pPager->errMask ) return; for(pPg=pPager->pAll; pPg; pPg=pNext){ pNext = pPg->pNextAll; sqliteFree(pPg); @@ -759,6 +844,29 @@ static void pager_reset(Pager *pPager){ assert( pPager->journalOpen==0 ); } +/* +** This function is used to reset the pager after a malloc() failure. This +** doesn't work with in-memory databases. If a malloc() fails when an +** in-memory database is in use it is not possible to recover. +** +** If a transaction or statement transaction is active, it is rolled back. +** +** It is an error to call this function if any pages are in use. +*/ +#ifndef SQLITE_OMIT_GLOBALRECOVER +int sqlite3pager_reset(Pager *pPager){ + if( pPager ){ + if( pPager->nRef || MEMDB ){ + return SQLITE_ERROR; + } + pPager->errMask &= ~(PAGER_ERR_MEM); + pager_reset(pPager); + } + return SQLITE_OK; +} +#endif + + /* ** When this routine is called, the pager has the journal file open and ** a RESERVED or EXCLUSIVE lock on the database. This routine releases @@ -772,7 +880,7 @@ static void pager_reset(Pager *pPager){ static int pager_unwritelock(Pager *pPager){ PgHdr *pPg; int rc; - assert( !pPager->memDb ); + assert( !MEMDB ); if( pPager->stateinJournal = 0; pPg->dirty = 0; pPg->needSync = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } pPager->dirtyCache = 0; pPager->nRec = 0; @@ -849,6 +960,12 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ u32 cksum; /* Checksum used for sanity checking */ u8 aData[SQLITE_MAX_PAGE_SIZE]; /* Temp storage for a page */ + /* useCksum should be true for the main journal and false for + ** statement journals. Verify that this is always the case + */ + assert( jfd == (useCksum ? &pPager->jfd : &pPager->stfd) ); + + rc = read32bits(jfd, &pgno); if( rc!=SQLITE_OK ) return rc; rc = sqlite3OsRead(jfd, &aData, pPager->pageSize); @@ -883,30 +1000,45 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int useCksum){ ** ** If in EXCLUSIVE state, then we update the pager cache if it exists ** and the main file. The page is then marked not dirty. + ** + ** Ticket #1171: The statement journal might contain page content that is + ** different from the page content at the start of the transaction. + ** This occurs when a page is changed prior to the start of a statement + ** then changed again within the statement. When rolling back such a + ** statement we must not write to the original database unless we know + ** for certain that original page contents are in the main rollback + ** journal. Otherwise, if a full ROLLBACK occurs after the statement + ** rollback the full ROLLBACK will not restore the page to its original + ** content. Two conditions must be met before writing to the database + ** files. (1) the database must be locked. (2) we know that the original + ** page content is in the main journal either because the page is not in + ** cache or else it is marked as needSync==0. */ pPg = pager_lookup(pPager, pgno); - assert( pPager->state>=PAGER_EXCLUSIVE || pPg ); - TRACE3("PLAYBACK %d page %d\n", pPager->fd.h, pgno); - if( pPager->state>=PAGER_EXCLUSIVE ){ + assert( pPager->state>=PAGER_EXCLUSIVE || pPg!=0 ); + TRACE3("PLAYBACK %d page %d\n", PAGERID(pPager), pgno); + if( pPager->state>=PAGER_EXCLUSIVE && (pPg==0 || pPg->needSync==0) ){ sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsWrite(&pPager->fd, aData, pPager->pageSize); + if( pPg ) pPg->dirty = 0; } if( pPg ){ - /* No page should ever be rolled back that is in use, except for page - ** 1 which is held in use in order to keep the lock on the database - ** active. + /* No page should ever be explicitly rolled back that is in use, except + ** for page 1 which is held in use in order to keep the lock on the + ** database active. However such a page may be rolled back as a result + ** of an internal error resulting in an automatic call to + ** sqlite3pager_rollback(). */ void *pData; - assert( pPg->nRef==0 || pPg->pgno==1 ); + /* assert( pPg->nRef==0 || pPg->pgno==1 ); */ pData = PGHDR_TO_DATA(pPg); memcpy(pData, aData, pPager->pageSize); if( pPager->xDestructor ){ /*** FIX ME: Should this be xReinit? ***/ pPager->xDestructor(pData, pPager->pageSize); } - if( pPager->state>=PAGER_EXCLUSIVE ){ - pPg->dirty = 0; - pPg->needSync = 0; - } +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif CODEC(pPager, pData, pPg->pgno, 3); } return rc; @@ -963,6 +1095,7 @@ static int pager_delmaster(const char *zMaster){ ** so, return without deleting the master journal file. */ OsFile journal; + int c; memset(&journal, 0, sizeof(journal)); rc = sqlite3OsOpenReadOnly(zJournal, &journal); @@ -976,7 +1109,9 @@ static int pager_delmaster(const char *zMaster){ goto delmaster_out; } - if( zMasterPtr && !strcmp(zMasterPtr, zMaster) ){ + c = zMasterPtr!=0 && strcmp(zMasterPtr, zMaster)==0; + sqliteFree(zMasterPtr); + if( c ){ /* We have a match. Do not delete the master journal file. */ goto delmaster_out; } @@ -1015,7 +1150,7 @@ static int pager_reload_cache(Pager *pPager){ if( (int)pPg->pgno <= pPager->origDbSize ){ sqlite3OsSeek(&pPager->fd, pPager->pageSize*(i64)(pPg->pgno-1)); rc = sqlite3OsRead(&pPager->fd, zBuf, pPager->pageSize); - TRACE3("REFETCH %d page %d\n", pPager->fd.h, pPg->pgno); + TRACE3("REFETCH %d page %d\n", PAGERID(pPager), pPg->pgno); if( rc ) break; CODEC(pPager, zBuf, pPg->pgno, 2); }else{ @@ -1031,6 +1166,9 @@ static int pager_reload_cache(Pager *pPager){ } pPg->needSync = 0; pPg->dirty = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } return rc; } @@ -1040,6 +1178,7 @@ static int pager_reload_cache(Pager *pPager){ ** indicated. */ static int pager_truncate(Pager *pPager, int nPage){ + assert( pPager->state>=PAGER_EXCLUSIVE ); return sqlite3OsTruncate(&pPager->fd, pPager->pageSize*(i64)nPage); } @@ -1159,7 +1298,8 @@ static int pager_playback(Pager *pPager){ /* If this is the first header read from the journal, truncate the ** database file back to it's original size. */ - if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ + if( pPager->state>=PAGER_EXCLUSIVE && + pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){ assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg ); rc = pager_truncate(pPager, mxPg); if( rc!=SQLITE_OK ){ @@ -1200,11 +1340,10 @@ end_playback: } if( zMaster ){ /* If there was a master journal and this routine will return true, - ** see if it is possible to delete the master journal. If errors - ** occur during this process, ignore them. + ** see if it is possible to delete the master journal. */ if( rc==SQLITE_OK ){ - pager_delmaster(zMaster); + rc = pager_delmaster(zMaster); } sqliteFree(zMaster); } @@ -1258,10 +1397,11 @@ static int pager_stmt_playback(Pager *pPager){ hdrOff = szJ; } - /* Truncate the database back to its original size. */ - rc = pager_truncate(pPager, pPager->stmtSize); + if( pPager->state>=PAGER_EXCLUSIVE ){ + rc = pager_truncate(pPager, pPager->stmtSize); + } pPager->dbSize = pPager->stmtSize; /* Figure out how many records are in the statement journal. @@ -1384,11 +1524,13 @@ void sqlite3pager_set_cachesize(Pager *pPager, int mxPage){ ** Numeric values associated with these states are OFF==1, NORMAL=2, ** and FULL=3. */ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS void sqlite3pager_set_safety_level(Pager *pPager, int level){ pPager->noSync = level==1 || pPager->tempFile; pPager->fullSync = level==3 && !pPager->tempFile; if( pPager->noSync ) pPager->needSync = 0; } +#endif /* ** Open a temporary file. Write the name of the file into zName @@ -1428,7 +1570,7 @@ int sqlite3pager_open( Pager **ppPager, /* Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ - int useJournal /* TRUE to use a rollback journal on this file */ + int flags /* flags controlling this file */ ){ Pager *pPager; char *zFullPathname = 0; @@ -1439,6 +1581,8 @@ int sqlite3pager_open( int tempFile = 0; int memDb = 0; int readOnly = 0; + int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; + int noReadlock = (flags & PAGER_NO_READLOCK)!=0; char zTemp[SQLITE_TEMPNAME_SIZE]; *ppPager = 0; @@ -1447,11 +1591,14 @@ int sqlite3pager_open( return SQLITE_NOMEM; } if( zFilename && zFilename[0] ){ +#ifndef SQLITE_OMIT_MEMORYDB if( strcmp(zFilename,":memory:")==0 ){ memDb = 1; zFullPathname = sqliteStrDup(""); rc = SQLITE_OK; - }else{ + }else +#endif + { zFullPathname = sqlite3OsFullPathname(zFilename); if( zFullPathname ){ rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly); @@ -1481,7 +1628,7 @@ int sqlite3pager_open( sqliteFree(zFullPathname); return SQLITE_NOMEM; } - TRACE3("OPEN %d %s\n", fd.h, zFullPathname); + TRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname); pPager->zFilename = (char*)&pPager[1]; pPager->zDirectory = &pPager->zFilename[nameLen+1]; pPager->zJournal = &pPager->zDirectory[nameLen+1]; @@ -1498,14 +1645,17 @@ int sqlite3pager_open( #endif pPager->journalOpen = 0; pPager->useJournal = useJournal && !memDb; + pPager->noReadlock = noReadlock && readOnly; pPager->stmtOpen = 0; pPager->stmtInUse = 0; pPager->nRef = 0; pPager->dbSize = memDb-1; pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE; + pPager->psAligned = FORCE_ALIGNMENT(pPager->pageSize); pPager->stmtSize = 0; pPager->stmtJSize = 0; pPager->nPage = 0; + pPager->nMaxPage = 0; pPager->mxPage = 100; pPager->state = PAGER_UNLOCK; pPager->errMask = 0; @@ -1518,7 +1668,7 @@ int sqlite3pager_open( pPager->pFirst = 0; pPager->pFirstSynced = 0; pPager->pLast = 0; - pPager->nExtra = nExtra; + pPager->nExtra = FORCE_ALIGNMENT(nExtra); pPager->sectorSize = PAGER_SECTOR_SIZE; pPager->pBusyHandler = 0; memset(pPager->aHash, 0, sizeof(pPager->aHash)); @@ -1564,6 +1714,7 @@ void sqlite3pager_set_reiniter(Pager *pPager, void (*xReinit)(void*,int)){ void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE ); pPager->pageSize = pageSize; + pPager->psAligned = FORCE_ALIGNMENT(pageSize); } /* @@ -1572,7 +1723,7 @@ void sqlite3pager_set_pagesize(Pager *pPager, int pageSize){ */ void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){ memset(pDest, 0, N); - if( pPager->memDb==0 ){ + if( MEMDB==0 ){ sqlite3OsSeek(&pPager->fd, 0); sqlite3OsRead(&pPager->fd, pDest, N); } @@ -1593,7 +1744,7 @@ int sqlite3pager_pagecount(Pager *pPager){ return 0; } n /= pPager->pageSize; - if( !pPager->memDb && n==PENDING_BYTE/pPager->pageSize ){ + if( !MEMDB && n==PENDING_BYTE/pPager->pageSize ){ n++; } if( pPager->state!=PAGER_UNLOCK ){ @@ -1608,6 +1759,33 @@ int sqlite3pager_pagecount(Pager *pPager){ static int syncJournal(Pager*); +/* +** Unlink pPg from it's hash chain. Also set the page number to 0 to indicate +** that the page is not part of any hash chain. This is required because the +** sqlite3pager_movepage() routine can leave a page in the +** pNextFree/pPrevFree list that is not a part of any hash-chain. +*/ +static void unlinkHashChain(Pager *pPager, PgHdr *pPg){ + if( pPg->pgno==0 ){ + /* If the page number is zero, then this page is not in any hash chain. */ + return; + } + if( pPg->pNextHash ){ + pPg->pNextHash->pPrevHash = pPg->pPrevHash; + } + if( pPg->pPrevHash ){ + assert( pPager->aHash[pager_hash(pPg->pgno)]!=pPg ); + pPg->pPrevHash->pNextHash = pPg->pNextHash; + }else{ + int h = pager_hash(pPg->pgno); + assert( pPager->aHash[h]==pPg ); + pPager->aHash[h] = pPg->pNextHash; + } + + pPg->pgno = 0; + pPg->pNextHash = pPg->pPrevHash = 0; +} + /* ** Unlink a page from the free list (the list of all pages where nRef==0) ** and from its hash collision chain. @@ -1638,19 +1816,10 @@ static void unlinkPage(PgHdr *pPg){ pPg->pNextFree = pPg->pPrevFree = 0; /* Unlink from the pgno hash table */ - if( pPg->pNextHash ){ - pPg->pNextHash->pPrevHash = pPg->pPrevHash; - } - if( pPg->pPrevHash ){ - pPg->pPrevHash->pNextHash = pPg->pNextHash; - }else{ - int h = pager_hash(pPg->pgno); - assert( pPager->aHash[h]==pPg ); - pPager->aHash[h] = pPg->pNextHash; - } - pPg->pNextHash = pPg->pPrevHash = 0; + unlinkHashChain(pPager, pPg); } +#ifndef SQLITE_OMIT_MEMORYDB /* ** This routine is used to truncate an in-memory database. Delete ** all pages whose pgno is larger than pPager->dbSize and is unreferenced. @@ -1676,6 +1845,40 @@ static void memoryTruncate(Pager *pPager){ } } } +#else +#define memoryTruncate(p) +#endif + +/* +** Try to obtain a lock on a file. Invoke the busy callback if the lock +** is currently not available. Repeate until the busy callback returns +** false or until the lock succeeds. +** +** Return SQLITE_OK on success and an error code if we cannot obtain +** the lock. +*/ +static int pager_wait_on_lock(Pager *pPager, int locktype){ + int rc; + assert( PAGER_SHARED==SHARED_LOCK ); + assert( PAGER_RESERVED==RESERVED_LOCK ); + assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); + if( pPager->state>=locktype ){ + rc = SQLITE_OK; + }else{ + int busy = 1; + BusyHandler *pH; + do { + rc = sqlite3OsLock(&pPager->fd, locktype); + }while( rc==SQLITE_BUSY && + (pH = pPager->pBusyHandler)!=0 && + pH->xFunc && pH->xFunc(pH->pArg, busy++) + ); + if( rc==SQLITE_OK ){ + pPager->state = locktype; + } + } + return rc; +} /* ** Truncate the file to the number of pages specified. @@ -1690,7 +1893,7 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ if( nPage>=(unsigned)pPager->dbSize ){ return SQLITE_OK; } - if( pPager->memDb ){ + if( MEMDB ){ pPager->dbSize = nPage; memoryTruncate(pPager); return SQLITE_OK; @@ -1699,6 +1902,13 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){ if( rc!=SQLITE_OK ){ return rc; } + + /* Get an exclusive lock on the database before truncating. */ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } + rc = pager_truncate(pPager, nPage); if( rc==SQLITE_OK ){ pPager->dbSize = nPage; @@ -1721,15 +1931,27 @@ int sqlite3pager_close(Pager *pPager){ case PAGER_RESERVED: case PAGER_SYNCED: case PAGER_EXCLUSIVE: { + /* We ignore any IO errors that occur during the rollback + ** operation. So disable IO error simulation so that testing + ** works more easily. + */ +#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN)) + extern int sqlite3_io_error_pending; + int ioerr_cnt = sqlite3_io_error_pending; + sqlite3_io_error_pending = -1; +#endif sqlite3pager_rollback(pPager); - if( !pPager->memDb ){ +#if defined(SQLITE_TEST) && (defined(OS_UNIX) || defined(OS_WIN)) + sqlite3_io_error_pending = ioerr_cnt; +#endif + if( !MEMDB ){ sqlite3OsUnlock(&pPager->fd, NO_LOCK); } - assert( pPager->journalOpen==0 ); + assert( pPager->errMask || pPager->journalOpen==0 ); break; } case PAGER_SHARED: { - if( !pPager->memDb ){ + if( !MEMDB ){ sqlite3OsUnlock(&pPager->fd, NO_LOCK); } break; @@ -1741,7 +1963,7 @@ int sqlite3pager_close(Pager *pPager){ } for(pPg=pPager->pAll; pPg; pPg=pNext){ #ifndef NDEBUG - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); assert( !pPg->alwaysRollback ); assert( !pHist->pOrig ); @@ -1751,20 +1973,21 @@ int sqlite3pager_close(Pager *pPager){ pNext = pPg->pNextAll; sqliteFree(pPg); } - TRACE2("CLOSE %d\n", pPager->fd.h); + TRACE2("CLOSE %d\n", PAGERID(pPager)); + assert( pPager->errMask || (pPager->journalOpen==0 && pPager->stmtOpen==0) ); + if( pPager->journalOpen ){ + sqlite3OsClose(&pPager->jfd); + } + if( pPager->stmtOpen ){ + sqlite3OsClose(&pPager->stfd); + } sqlite3OsClose(&pPager->fd); - assert( pPager->journalOpen==0 ); /* Temp files are automatically deleted by the OS ** if( pPager->tempFile ){ ** sqlite3OsDelete(pPager->zFilename); ** } */ - if( pPager->zFilename!=(char*)&pPager[1] ){ - assert( 0 ); /* Cannot happen */ - sqliteFree(pPager->zFilename); - sqliteFree(pPager->zJournal); - sqliteFree(pPager->zDirectory); - } + sqliteFree(pPager); return SQLITE_OK; } @@ -1809,7 +2032,7 @@ static void _page_ref(PgHdr *pPg){ pPg->nRef++; REFINFO(pPg); } -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG static void page_ref(PgHdr *pPg){ if( pPg->nRef==0 ){ _page_ref(pPg); @@ -1882,7 +2105,7 @@ static int syncJournal(Pager *pPager){ ** it as a candidate for rollback. */ if( pPager->fullSync ){ - TRACE2("SYNC journal of %d\n", pPager->fd.h); + TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd); if( rc!=0 ) return rc; } @@ -1892,7 +2115,7 @@ static int syncJournal(Pager *pPager){ sqlite3OsSeek(&pPager->jfd, pPager->journalOff); } - TRACE2("SYNC journal of %d\n", pPager->fd.h); + TRACE2("SYNC journal of %d\n", PAGERID(pPager)); rc = sqlite3OsSync(&pPager->jfd); if( rc!=0 ) return rc; pPager->journalStarted = 1; @@ -1923,37 +2146,6 @@ static int syncJournal(Pager *pPager){ return rc; } -/* -** Try to obtain a lock on a file. Invoke the busy callback if the lock -** is currently not available. Repeate until the busy callback returns -** false or until the lock succeeds. -** -** Return SQLITE_OK on success and an error code if we cannot obtain -** the lock. -*/ -static int pager_wait_on_lock(Pager *pPager, int locktype){ - int rc; - assert( PAGER_SHARED==SHARED_LOCK ); - assert( PAGER_RESERVED==RESERVED_LOCK ); - assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK ); - if( pPager->state>=locktype ){ - rc = SQLITE_OK; - }else{ - int busy = 1; - do { - rc = sqlite3OsLock(&pPager->fd, locktype); - }while( rc==SQLITE_BUSY && - pPager->pBusyHandler && - pPager->pBusyHandler->xFunc && - pPager->pBusyHandler->xFunc(pPager->pBusyHandler->pArg, busy++) - ); - if( rc==SQLITE_OK ){ - pPager->state = locktype; - } - } - return rc; -} - /* ** Given a list of pages (connected by the PgHdr.pDirty pointer) write ** every one of those pages out to the database file and mark them all @@ -1990,12 +2182,28 @@ static int pager_write_pagelist(PgHdr *pList){ while( pList ){ assert( pList->dirty ); sqlite3OsSeek(&pPager->fd, (pList->pgno-1)*(i64)pPager->pageSize); - CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); - TRACE3("STORE %d page %d\n", pPager->fd.h, pList->pgno); - rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize); - CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); + /* If there are dirty pages in the page cache with page numbers greater + ** than Pager.dbSize, this means sqlite3pager_truncate() was called to + ** make the file smaller (presumably by auto-vacuum code). Do not write + ** any such pages to the file. + */ + if( pList->pgno<=pPager->dbSize ){ + CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6); + TRACE3("STORE %d page %d\n", PAGERID(pPager), pList->pgno); + rc = sqlite3OsWrite(&pPager->fd, PGHDR_TO_DATA(pList), pPager->pageSize); + CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0); + pPager->nWrite++; + } +#ifndef NDEBUG + else{ + TRACE3("NOSTORE %d page %d\n", PAGERID(pPager), pList->pgno); + } +#endif if( rc ) return rc; pList->dirty = 0; +#ifdef SQLITE_CHECK_PAGES + pList->pageHash = pager_pagehash(pList); +#endif pList = pList->pDirty; } return SQLITE_OK; @@ -2018,6 +2226,26 @@ static PgHdr *pager_get_all_dirty_pages(Pager *pPager){ return pList; } +/* +** Return TRUE if there is a hot journal on the given pager. +** A hot journal is one that needs to be played back. +** +** If the current size of the database file is 0 but a journal file +** exists, that is probably an old journal left over from a prior +** database with the same name. Just delete the journal. +*/ +static int hasHotJournal(Pager *pPager){ + if( !pPager->useJournal ) return 0; + if( !sqlite3OsFileExists(pPager->zJournal) ) return 0; + if( sqlite3OsCheckReservedLock(&pPager->fd) ) return 0; + if( sqlite3pager_pagecount(pPager)==0 ){ + sqlite3OsDelete(pPager->zJournal); + return 0; + }else{ + return 1; + } +} + /* ** Acquire a page. ** @@ -2045,10 +2273,16 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ PgHdr *pPg; int rc; + /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page + ** number greater than this, or zero, is requested. + */ + if( pgno>PAGER_MAX_PGNO || pgno==0 ){ + return SQLITE_CORRUPT; + } + /* Make sure we have not hit any critical errors. */ assert( pPager!=0 ); - assert( pgno!=0 ); *ppPage = 0; if( pPager->errMask & ~(PAGER_ERR_FULL) ){ return pager_errcode(pPager); @@ -2057,19 +2291,18 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* If this is the first page accessed, then get a SHARED lock ** on the database file. */ - if( pPager->nRef==0 && !pPager->memDb ){ - rc = pager_wait_on_lock(pPager, SHARED_LOCK); - if( rc!=SQLITE_OK ){ - return rc; + if( pPager->nRef==0 && !MEMDB ){ + if( !pPager->noReadlock ){ + rc = pager_wait_on_lock(pPager, SHARED_LOCK); + if( rc!=SQLITE_OK ){ + return rc; + } } /* If a journal file exists, and there is no RESERVED lock on the ** database file, then it either needs to be played back or deleted. */ - if( pPager->useJournal && - sqlite3OsFileExists(pPager->zJournal) && - !sqlite3OsCheckReservedLock(&pPager->fd) - ){ + if( hasHotJournal(pPager) ){ int rc; /* Get an EXCLUSIVE lock on the database file. At this point it is @@ -2123,7 +2356,7 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ /* Search for page in cache */ pPg = pager_lookup(pPager, pgno); - if( pPager->memDb && pPager->state==PAGER_UNLOCK ){ + if( MEMDB && pPager->state==PAGER_UNLOCK ){ pPager->state = PAGER_SHARED; } } @@ -2131,26 +2364,27 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ /* The requested page is not in the page cache. */ int h; pPager->nMiss++; - if( pPager->nPagemxPage || pPager->pFirst==0 || pPager->memDb ){ + if( pPager->nPagemxPage || pPager->pFirst==0 || MEMDB ){ /* Create a new page */ - pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->pageSize + pPg = sqliteMallocRaw( sizeof(*pPg) + pPager->psAligned + sizeof(u32) + pPager->nExtra - + pPager->memDb*sizeof(PgHistory) ); + + MEMDB*sizeof(PgHistory) ); if( pPg==0 ){ - if( !pPager->memDb ){ - pager_unwritelock(pPager); - } pPager->errMask |= PAGER_ERR_MEM; return SQLITE_NOMEM; } memset(pPg, 0, sizeof(*pPg)); - if( pPager->memDb ){ + if( MEMDB ){ memset(PGHDR_TO_HIST(pPg, pPager), 0, sizeof(PgHistory)); } pPg->pPager = pPager; pPg->pNextAll = pPager->pAll; pPager->pAll = pPg; pPager->nPage++; + if( pPager->nPage>pPager->nMaxPage ){ + assert( pPager->nMaxPage==(pPager->nPage-1) ); + pPager->nMaxPage++; + } }else{ /* Find a page to recycle. Try to locate a page that does not ** require us to do an fsync() on the journal. @@ -2247,20 +2481,19 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ if( pPager->nExtra>0 ){ memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra); } - sqlite3pager_pagecount(pPager); if( pPager->errMask!=0 ){ sqlite3pager_unref(PGHDR_TO_DATA(pPg)); rc = pager_errcode(pPager); return rc; } - if( pPager->dbSize<(int)pgno ){ + if( sqlite3pager_pagecount(pPager)<(int)pgno ){ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); }else{ int rc; - assert( pPager->memDb==0 ); + assert( MEMDB==0 ); sqlite3OsSeek(&pPager->fd, (pgno-1)*(i64)pPager->pageSize); rc = sqlite3OsRead(&pPager->fd, PGHDR_TO_DATA(pPg), pPager->pageSize); - TRACE3("FETCH %d page %d\n", pPager->fd.h, pPg->pgno); + TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3); if( rc!=SQLITE_OK ){ i64 fileSize; @@ -2271,8 +2504,13 @@ int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage){ }else{ memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize); } + }else{ + pPager->nRead++; } } +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif }else{ /* The requested page is in the page cache. */ pPager->nHit++; @@ -2325,6 +2563,8 @@ int sqlite3pager_unref(void *pData){ pPg->nRef--; REFINFO(pPg); + CHECK_PAGE(pPg); + /* When the number of references to a page reach 0, call the ** destructor and add the page to the freelist. */ @@ -2351,7 +2591,7 @@ int sqlite3pager_unref(void *pData){ */ pPager->nRef--; assert( pPager->nRef>=0 ); - if( pPager->nRef==0 && !pPager->memDb ){ + if( pPager->nRef==0 && !MEMDB ){ pager_reset(pPager); } } @@ -2367,7 +2607,7 @@ int sqlite3pager_unref(void *pData){ */ static int pager_open_journal(Pager *pPager){ int rc; - assert( !pPager->memDb ); + assert( !MEMDB ); assert( pPager->state>=PAGER_RESERVED ); assert( pPager->journalOpen==0 ); assert( pPager->useJournal ); @@ -2384,6 +2624,8 @@ static int pager_open_journal(Pager *pPager){ if( rc!=SQLITE_OK ){ goto failed_to_open_journal; } + SET_FULLSYNC(pPager->jfd, pPager->fullSync); + SET_FULLSYNC(pPager->fd, pPager->fullSync); sqlite3OsOpenDirectory(pPager->zDirectory, &pPager->jfd); pPager->journalOpen = 1; pPager->journalStarted = 0; @@ -2452,15 +2694,11 @@ int sqlite3pager_begin(void *pData, int exFlag){ assert( pPager->state!=PAGER_UNLOCK ); if( pPager->state==PAGER_SHARED ){ assert( pPager->aInJournal==0 ); - if( pPager->memDb ){ + if( MEMDB ){ pPager->state = PAGER_EXCLUSIVE; pPager->origDbSize = pPager->dbSize; }else{ - if( SQLITE_BUSY_RESERVED_LOCK || exFlag ){ - rc = pager_wait_on_lock(pPager, RESERVED_LOCK); - }else{ - rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK); - } + rc = sqlite3OsLock(&pPager->fd, RESERVED_LOCK); if( rc==SQLITE_OK ){ pPager->state = PAGER_RESERVED; if( exFlag ){ @@ -2471,7 +2709,7 @@ int sqlite3pager_begin(void *pData, int exFlag){ return rc; } pPager->dirtyCache = 0; - TRACE2("TRANSACTION %d\n", pPager->fd.h); + TRACE2("TRANSACTION %d\n", PAGERID(pPager)); if( pPager->useJournal && !pPager->tempFile ){ rc = pager_open_journal(pPager); } @@ -2513,128 +2751,130 @@ int sqlite3pager_write(void *pData){ assert( !pPager->setMaster ); + CHECK_PAGE(pPg); + /* Mark the page as dirty. If the page has already been written ** to the journal then we can return right away. */ pPg->dirty = 1; if( pPg->inJournal && (pPg->inStmt || pPager->stmtInUse==0) ){ pPager->dirtyCache = 1; - return SQLITE_OK; - } + }else{ - /* If we get this far, it means that the page needs to be - ** written to the transaction journal or the ckeckpoint journal - ** or both. - ** - ** First check to see that the transaction journal exists and - ** create it if it does not. - */ - assert( pPager->state!=PAGER_UNLOCK ); - rc = sqlite3pager_begin(pData, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - assert( pPager->state>=PAGER_RESERVED ); - if( !pPager->journalOpen && pPager->useJournal ){ - rc = pager_open_journal(pPager); - if( rc!=SQLITE_OK ) return rc; - } - assert( pPager->journalOpen || !pPager->useJournal ); - pPager->dirtyCache = 1; - - /* The transaction journal now exists and we have a RESERVED or an - ** EXCLUSIVE lock on the main database file. Write the current page to - ** the transaction journal if it is not there already. - */ - if( !pPg->inJournal && (pPager->useJournal || pPager->memDb) ){ - if( (int)pPg->pgno <= pPager->origDbSize ){ - int szPg; - u32 saved; - if( pPager->memDb ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - TRACE3("JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); - assert( pHist->pOrig==0 ); - pHist->pOrig = sqliteMallocRaw( pPager->pageSize ); - if( pHist->pOrig ){ - memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); + /* If we get this far, it means that the page needs to be + ** written to the transaction journal or the ckeckpoint journal + ** or both. + ** + ** First check to see that the transaction journal exists and + ** create it if it does not. + */ + assert( pPager->state!=PAGER_UNLOCK ); + rc = sqlite3pager_begin(pData, 0); + if( rc!=SQLITE_OK ){ + return rc; + } + assert( pPager->state>=PAGER_RESERVED ); + if( !pPager->journalOpen && pPager->useJournal ){ + rc = pager_open_journal(pPager); + if( rc!=SQLITE_OK ) return rc; + } + assert( pPager->journalOpen || !pPager->useJournal ); + pPager->dirtyCache = 1; + + /* The transaction journal now exists and we have a RESERVED or an + ** EXCLUSIVE lock on the main database file. Write the current page to + ** the transaction journal if it is not there already. + */ + if( !pPg->inJournal && (pPager->useJournal || MEMDB) ){ + if( (int)pPg->pgno <= pPager->origDbSize ){ + int szPg; + u32 saved; + if( MEMDB ){ + PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); + TRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); + assert( pHist->pOrig==0 ); + pHist->pOrig = sqliteMallocRaw( pPager->pageSize ); + if( pHist->pOrig ){ + memcpy(pHist->pOrig, PGHDR_TO_DATA(pPg), pPager->pageSize); + } + }else{ + u32 cksum; + CODEC(pPager, pData, pPg->pgno, 7); + cksum = pager_cksum(pPager, pPg->pgno, pData); + saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager); + store32bits(cksum, pPg, pPager->pageSize); + szPg = pPager->pageSize+8; + store32bits(pPg->pgno, pPg, -4); + rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); + pPager->journalOff += szPg; + TRACE4("JOURNAL %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, pPg->needSync); + CODEC(pPager, pData, pPg->pgno, 0); + *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved; + if( rc!=SQLITE_OK ){ + sqlite3pager_rollback(pPager); + pPager->errMask |= PAGER_ERR_FULL; + return rc; + } + pPager->nRec++; + assert( pPager->aInJournal!=0 ); + pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); + pPg->needSync = !pPager->noSync; + if( pPager->stmtInUse ){ + pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); + page_add_to_stmt_list(pPg); + } } }else{ - u32 cksum; - CODEC(pPager, pData, pPg->pgno, 7); - cksum = pager_cksum(pPager, pPg->pgno, pData); - saved = *(u32*)PGHDR_TO_EXTRA(pPg, pPager); - store32bits(cksum, pPg, pPager->pageSize); - szPg = pPager->pageSize+8; + pPg->needSync = !pPager->journalStarted && !pPager->noSync; + TRACE4("APPEND %d page %d needSync=%d\n", + PAGERID(pPager), pPg->pgno, pPg->needSync); + } + if( pPg->needSync ){ + pPager->needSync = 1; + } + pPg->inJournal = 1; + } + + /* If the statement journal is open and the page is not in it, + ** then write the current page to the statement journal. Note that + ** the statement journal format differs from the standard journal format + ** in that it omits the checksums and the header. + */ + if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ + assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); + if( MEMDB ){ + PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); + assert( pHist->pStmt==0 ); + pHist->pStmt = sqliteMallocRaw( pPager->pageSize ); + if( pHist->pStmt ){ + memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); + } + TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); + }else{ store32bits(pPg->pgno, pPg, -4); - rc = sqlite3OsWrite(&pPager->jfd, &((char*)pData)[-4], szPg); - pPager->journalOff += szPg; - TRACE4("JOURNAL %d page %d needSync=%d\n", - pPager->fd.h, pPg->pgno, pPg->needSync); + CODEC(pPager, pData, pPg->pgno, 7); + rc = sqlite3OsWrite(&pPager->stfd,((char*)pData)-4, pPager->pageSize+4); + TRACE3("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno); CODEC(pPager, pData, pPg->pgno, 0); - *(u32*)PGHDR_TO_EXTRA(pPg, pPager) = saved; if( rc!=SQLITE_OK ){ sqlite3pager_rollback(pPager); pPager->errMask |= PAGER_ERR_FULL; return rc; } - pPager->nRec++; - assert( pPager->aInJournal!=0 ); - pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); - pPg->needSync = !pPager->noSync; - if( pPager->stmtInUse ){ - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - page_add_to_stmt_list(pPg); - } + pPager->stmtNRec++; + assert( pPager->aInStmt!=0 ); + pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); } - }else{ - pPg->needSync = !pPager->journalStarted && !pPager->noSync; - TRACE4("APPEND %d page %d needSync=%d\n", - pPager->fd.h, pPg->pgno, pPg->needSync); + page_add_to_stmt_list(pPg); } - if( pPg->needSync ){ - pPager->needSync = 1; - } - pPg->inJournal = 1; - } - - /* If the statement journal is open and the page is not in it, - ** then write the current page to the statement journal. Note that - ** the statement journal format differs from the standard journal format - ** in that it omits the checksums and the header. - */ - if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ - assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); - if( pPager->memDb ){ - PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); - assert( pHist->pStmt==0 ); - pHist->pStmt = sqliteMallocRaw( pPager->pageSize ); - if( pHist->pStmt ){ - memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize); - } - TRACE3("STMT-JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); - }else{ - store32bits(pPg->pgno, pPg, -4); - CODEC(pPager, pData, pPg->pgno, 7); - rc = sqlite3OsWrite(&pPager->stfd, ((char*)pData)-4, pPager->pageSize+4); - TRACE3("STMT-JOURNAL %d page %d\n", pPager->fd.h, pPg->pgno); - CODEC(pPager, pData, pPg->pgno, 0); - if( rc!=SQLITE_OK ){ - sqlite3pager_rollback(pPager); - pPager->errMask |= PAGER_ERR_FULL; - return rc; - } - pPager->stmtNRec++; - assert( pPager->aInStmt!=0 ); - pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); - } - page_add_to_stmt_list(pPg); } /* Update the database size and return. */ if( pPager->dbSize<(int)pPg->pgno ){ pPager->dbSize = pPg->pgno; - if( !pPager->memDb && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ + if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){ pPager->dbSize++; } } @@ -2651,6 +2891,7 @@ int sqlite3pager_iswriteable(void *pData){ return pPg->dirty; } +#ifndef SQLITE_OMIT_VACUUM /* ** Replace the content of a single page with the information in the third ** argument. @@ -2669,6 +2910,7 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){ } return rc; } +#endif /* ** A call to this routine tells the pager that it is not necessary to @@ -2697,7 +2939,7 @@ int sqlite3pager_overwrite(Pager *pPager, Pgno pgno, void *pData){ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ PgHdr *pPg; - if( pPager->memDb ) return; + if( MEMDB ) return; pPg = pager_lookup(pPager, pgno); pPg->alwaysRollback = 1; @@ -2712,8 +2954,11 @@ void sqlite3pager_dont_write(Pager *pPager, Pgno pgno){ ** corruption during the next transaction. */ }else{ - TRACE3("DONT_WRITE page %d of %d\n", pgno, pPager->fd.h); + TRACE3("DONT_WRITE page %d of %d\n", pgno, PAGERID(pPager)); pPg->dirty = 0; +#ifdef SQLITE_CHECK_PAGES + pPg->pageHash = pager_pagehash(pPg); +#endif } } } @@ -2729,7 +2974,7 @@ void sqlite3pager_dont_rollback(void *pData){ Pager *pPager = pPg->pPager; if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return; - if( pPg->alwaysRollback || pPager->alwaysRollback || pPager->memDb ) return; + if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return; if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){ assert( pPager->aInJournal!=0 ); pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7); @@ -2738,7 +2983,7 @@ void sqlite3pager_dont_rollback(void *pData){ pPager->aInStmt[pPg->pgno/8] |= 1<<(pPg->pgno&7); page_add_to_stmt_list(pPg); } - TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, pPager->fd.h); + TRACE3("DONT_ROLLBACK page %d of %d\n", pPg->pgno, PAGERID(pPager)); } if( pPager->stmtInUse && !pPg->inStmt && (int)pPg->pgno<=pPager->stmtSize ){ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize ); @@ -2749,6 +2994,7 @@ void sqlite3pager_dont_rollback(void *pData){ } +#ifndef SQLITE_OMIT_MEMORYDB /* ** Clear a PgHistory block */ @@ -2758,6 +3004,9 @@ static void clearHistory(PgHistory *pHist){ pHist->pOrig = 0; pHist->pStmt = 0; } +#else +#define clearHistory(x) +#endif /* ** Commit all changes to the database and release the write lock. @@ -2784,8 +3033,8 @@ int sqlite3pager_commit(Pager *pPager){ if( pPager->statefd.h); - if( pPager->memDb ){ + TRACE2("COMMIT %d\n", PAGERID(pPager)); + if( MEMDB ){ pPg = pager_get_all_dirty_pages(pPager); while( pPg ){ clearHistory(PGHDR_TO_HIST(pPg, pPager)); @@ -2816,7 +3065,7 @@ int sqlite3pager_commit(Pager *pPager){ return rc; } assert( pPager->journalOpen ); - rc = sqlite3pager_sync(pPager, 0); + rc = sqlite3pager_sync(pPager, 0, 0); if( rc!=SQLITE_OK ){ goto commit_abort; } @@ -2845,8 +3094,8 @@ commit_abort: */ int sqlite3pager_rollback(Pager *pPager){ int rc; - TRACE2("ROLLBACK %d\n", pPager->fd.h); - if( pPager->memDb ){ + TRACE2("ROLLBACK %d\n", PAGERID(pPager)); + if( MEMDB ){ PgHdr *p; for(p=pPager->pAll; p; p=p->pNextAll){ PgHistory *pHist; @@ -2860,9 +3109,9 @@ int sqlite3pager_rollback(Pager *pPager){ pHist = PGHDR_TO_HIST(p, pPager); if( pHist->pOrig ){ memcpy(PGHDR_TO_DATA(p), pHist->pOrig, pPager->pageSize); - TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, pPager->fd.h); + TRACE3("ROLLBACK-PAGE %d of %d\n", p->pgno, PAGERID(pPager)); }else{ - TRACE3("PAGE %d is clean on %d\n", p->pgno, pPager->fd.h); + TRACE3("PAGE %d is clean on %d\n", p->pgno, PAGERID(pPager)); } clearHistory(pHist); p->dirty = 0; @@ -2896,13 +3145,11 @@ int sqlite3pager_rollback(Pager *pPager){ return pager_errcode(pPager); } if( pPager->state==PAGER_RESERVED ){ - int rc2, rc3; + int rc2; rc = pager_reload_cache(pPager); - rc2 = pager_truncate(pPager, pPager->origDbSize); - rc3 = pager_unwritelock(pPager); + rc2 = pager_unwritelock(pPager); if( rc==SQLITE_OK ){ rc = rc2; - if( rc3 ) rc = rc3; } }else{ rc = pager_playback(pPager); @@ -2927,7 +3174,7 @@ int sqlite3pager_isreadonly(Pager *pPager){ ** This routine is used for testing and analysis only. */ int *sqlite3pager_stats(Pager *pPager){ - static int a[9]; + static int a[11]; a[0] = pPager->nRef; a[1] = pPager->nPage; a[2] = pPager->mxPage; @@ -2937,6 +3184,8 @@ int *sqlite3pager_stats(Pager *pPager){ a[6] = pPager->nHit; a[7] = pPager->nMiss; a[8] = pPager->nOvfl; + a[9] = pPager->nRead; + a[10] = pPager->nWrite; return a; } @@ -2952,8 +3201,8 @@ int sqlite3pager_stmt_begin(Pager *pPager){ char zTemp[SQLITE_TEMPNAME_SIZE]; assert( !pPager->stmtInUse ); assert( pPager->dbSize>=0 ); - TRACE2("STMT-BEGIN %d\n", pPager->fd.h); - if( pPager->memDb ){ + TRACE2("STMT-BEGIN %d\n", PAGERID(pPager)); + if( MEMDB ){ pPager->stmtInUse = 1; pPager->stmtSize = pPager->dbSize; return SQLITE_OK; @@ -3000,8 +3249,8 @@ stmt_begin_failed: int sqlite3pager_stmt_commit(Pager *pPager){ if( pPager->stmtInUse ){ PgHdr *pPg, *pNext; - TRACE2("STMT-COMMIT %d\n", pPager->fd.h); - if( !pPager->memDb ){ + TRACE2("STMT-COMMIT %d\n", PAGERID(pPager)); + if( !MEMDB ){ sqlite3OsSeek(&pPager->stfd, 0); /* sqlite3OsTruncate(&pPager->stfd, 0); */ sqliteFree( pPager->aInStmt ); @@ -3012,7 +3261,7 @@ int sqlite3pager_stmt_commit(Pager *pPager){ assert( pPg->inStmt ); pPg->inStmt = 0; pPg->pPrevStmt = pPg->pNextStmt = 0; - if( pPager->memDb ){ + if( MEMDB ){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); sqliteFree(pHist->pStmt); pHist->pStmt = 0; @@ -3032,8 +3281,8 @@ int sqlite3pager_stmt_commit(Pager *pPager){ int sqlite3pager_stmt_rollback(Pager *pPager){ int rc; if( pPager->stmtInUse ){ - TRACE2("STMT-ROLLBACK %d\n", pPager->fd.h); - if( pPager->memDb ){ + TRACE2("STMT-ROLLBACK %d\n", PAGERID(pPager)); + if( MEMDB ){ PgHdr *pPg; for(pPg=pPager->pStmt; pPg; pPg=pPg->pNextStmt){ PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager); @@ -3132,14 +3381,20 @@ static int pager_incr_changecounter(Pager *pPager){ ** ** Note that if zMaster==NULL, this does not overwrite a previous value ** passed to an sqlite3pager_sync() call. +** +** If parameter nTrunc is non-zero, then the pager file is truncated to +** nTrunc pages (this is used by auto-vacuum databases). */ -int sqlite3pager_sync(Pager *pPager, const char *zMaster){ +int sqlite3pager_sync(Pager *pPager, const char *zMaster, Pgno nTrunc){ int rc = SQLITE_OK; + TRACE4("DATABASE SYNC: File=%s zMaster=%s nTrunc=%d\n", + pPager->zFilename, zMaster, nTrunc); + /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is a no-op. */ - if( pPager->state!=PAGER_SYNCED && !pPager->memDb && pPager->dirtyCache ){ + if( pPager->state!=PAGER_SYNCED && !MEMDB && pPager->dirtyCache ){ PgHdr *pPg; assert( pPager->journalOpen ); @@ -3152,12 +3407,38 @@ int sqlite3pager_sync(Pager *pPager, const char *zMaster){ if( !pPager->setMaster ){ rc = pager_incr_changecounter(pPager); if( rc!=SQLITE_OK ) goto sync_exit; +#ifndef SQLITE_OMIT_AUTOVACUUM + if( nTrunc!=0 ){ + /* If this transaction has made the database smaller, then all pages + ** being discarded by the truncation must be written to the journal + ** file. + */ + Pgno i; + void *pPage; + for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){ + if( !(pPager->aInJournal[i/8] & (1<<(i&7))) ){ + rc = sqlite3pager_get(pPager, i, &pPage); + if( rc!=SQLITE_OK ) goto sync_exit; + rc = sqlite3pager_write(pPage); + sqlite3pager_unref(pPage); + if( rc!=SQLITE_OK ) goto sync_exit; + } + } + } +#endif rc = writeMasterJournal(pPager, zMaster); if( rc!=SQLITE_OK ) goto sync_exit; rc = syncJournal(pPager); if( rc!=SQLITE_OK ) goto sync_exit; } +#ifndef SQLITE_OMIT_AUTOVACUUM + if( nTrunc!=0 ){ + rc = sqlite3pager_truncate(pPager, nTrunc); + if( rc!=SQLITE_OK ) goto sync_exit; + } +#endif + /* Write all dirty pages to the database file */ pPg = pager_get_all_dirty_pages(pPager); rc = pager_write_pagelist(pPg); @@ -3175,6 +3456,103 @@ sync_exit: return rc; } +#ifndef SQLITE_OMIT_AUTOVACUUM +/* +** Move the page identified by pData to location pgno in the file. +** +** There must be no references to the current page pgno. If current page +** pgno is not already in the rollback journal, it is not written there by +** by this routine. The same applies to the page pData refers to on entry to +** this routine. +** +** References to the page refered to by pData remain valid. Updating any +** meta-data associated with page pData (i.e. data stored in the nExtra bytes +** allocated along with the page) is the responsibility of the caller. +** +** A transaction must be active when this routine is called. It used to be +** required that a statement transaction was not active, but this restriction +** has been removed (CREATE INDEX needs to move a page when a statement +** transaction is active). +*/ +int sqlite3pager_movepage(Pager *pPager, void *pData, Pgno pgno){ + PgHdr *pPg = DATA_TO_PGHDR(pData); + PgHdr *pPgOld; + int h; + Pgno needSyncPgno = 0; + + assert( pPg->nRef>0 ); + + TRACE5("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERID(pPager), pPg->pgno, pPg->needSync, pgno); + + if( pPg->needSync ){ + needSyncPgno = pPg->pgno; + assert( pPg->inJournal ); + assert( pPg->dirty ); + assert( pPager->needSync ); + } + + /* Unlink pPg from it's hash-chain */ + unlinkHashChain(pPager, pPg); + + /* If the cache contains a page with page-number pgno, remove it + ** from it's hash chain. Also, if the PgHdr.needSync was set for + ** page pgno before the 'move' operation, it needs to be retained + ** for the page moved there. + */ + pPgOld = pager_lookup(pPager, pgno); + if( pPgOld ){ + assert( pPgOld->nRef==0 ); + unlinkHashChain(pPager, pPgOld); + pPgOld->dirty = 0; + if( pPgOld->needSync ){ + assert( pPgOld->inJournal ); + pPg->inJournal = 1; + pPg->needSync = 1; + assert( pPager->needSync ); + } + } + + /* Change the page number for pPg and insert it into the new hash-chain. */ + pPg->pgno = pgno; + h = pager_hash(pgno); + if( pPager->aHash[h] ){ + assert( pPager->aHash[h]->pPrevHash==0 ); + pPager->aHash[h]->pPrevHash = pPg; + } + pPg->pNextHash = pPager->aHash[h]; + pPager->aHash[h] = pPg; + pPg->pPrevHash = 0; + + pPg->dirty = 1; + pPager->dirtyCache = 1; + + if( needSyncPgno ){ + /* If needSyncPgno is non-zero, then the journal file needs to be + ** sync()ed before any data is written to database file page needSyncPgno. + ** Currently, no such page exists in the page-cache and the + ** Pager.aInJournal bit has been set. This needs to be remedied by loading + ** the page into the pager-cache and setting the PgHdr.needSync flag. + ** + ** The sqlite3pager_get() call may cause the journal to sync. So make + ** sure the Pager.needSync flag is set too. + */ + int rc; + void *pNeedSync; + assert( pPager->needSync ); + rc = sqlite3pager_get(pPager, needSyncPgno, &pNeedSync); + if( rc!=SQLITE_OK ) return rc; + pPager->needSync = 1; + DATA_TO_PGHDR(pNeedSync)->needSync = 1; + DATA_TO_PGHDR(pNeedSync)->inJournal = 1; + DATA_TO_PGHDR(pNeedSync)->dirty = 1; + sqlite3pager_unref(pNeedSync); + } + + return SQLITE_OK; +} +#endif + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Return the current state of the file lock for the given pager. @@ -3190,7 +3568,7 @@ int sqlite3pager_lockstate(Pager *pPager){ } #endif -#ifdef SQLITE_TEST +#ifdef SQLITE_DEBUG /* ** Print a listing of all referenced pages and their ref count. */ diff --git a/db/sqlite3/src/pager.h b/db/sqlite3/src/pager.h index ff6dd873386..442df76a45b 100644 --- a/db/sqlite3/src/pager.h +++ b/db/sqlite3/src/pager.h @@ -13,7 +13,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.38 2004/10/05 02:41:43 drh Exp $ +** @(#) $Id: pager.h,v 1.42 2005/03/21 04:04:03 danielk1977 Exp $ */ /* @@ -50,13 +50,21 @@ typedef unsigned int Pgno; */ typedef struct Pager Pager; +/* +** Allowed values for the flags parameter to sqlite3pager_open(). +** +** NOTE: This values must match the corresponding BTREE_ values in btree.h. +*/ +#define PAGER_OMIT_JOURNAL 0x0001 /* Do not use a rollback journal */ +#define PAGER_NO_READLOCK 0x0002 /* Omit readlocks on readonly files */ + /* ** See source code comments for a detailed description of the following ** routines: */ int sqlite3pager_open(Pager **ppPager, const char *zFilename, - int nExtra, int useJournal); + int nExtra, int flags); void sqlite3pager_set_busyhandler(Pager*, BusyHandler *pBusyHandler); void sqlite3pager_set_destructor(Pager*, void(*)(void*,int)); void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int)); @@ -76,7 +84,7 @@ int sqlite3pager_pagecount(Pager*); int sqlite3pager_truncate(Pager*,Pgno); int sqlite3pager_begin(void*, int exFlag); int sqlite3pager_commit(Pager*); -int sqlite3pager_sync(Pager*,const char *zMaster); +int sqlite3pager_sync(Pager*,const char *zMaster, Pgno); int sqlite3pager_rollback(Pager*); int sqlite3pager_isreadonly(Pager*); int sqlite3pager_stmt_begin(Pager*); @@ -91,6 +99,8 @@ const char *sqlite3pager_dirname(Pager*); const char *sqlite3pager_journalname(Pager*); int sqlite3pager_rename(Pager*, const char *zNewName); void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*); +int sqlite3pager_movepage(Pager*,void*,Pgno); +int sqlite3pager_reset(Pager*); #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) int sqlite3pager_lockstate(Pager*); diff --git a/db/sqlite3/src/parse.c b/db/sqlite3/src/parse.c index 9443c6fc42c..65591aaf2a7 100644 --- a/db/sqlite3/src/parse.c +++ b/db/sqlite3/src/parse.c @@ -14,8 +14,8 @@ ** LIMIT clause of a SELECT statement. */ struct LimitVal { - int limit; /* The LIMIT value. -1 if there is no limit */ - int offset; /* The OFFSET. 0 if there is none */ + Expr *pLimit; /* The LIMIT expression. NULL if there is no limit */ + Expr *pOffset; /* The OFFSET expression. NULL if there is none */ }; /* @@ -93,35 +93,35 @@ struct AttachKey { int type; Token key; }; ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 225 +#define YYNOCODE 243 #define YYACTIONTYPE unsigned short int #define sqlite3ParserTOKENTYPE Token typedef union { sqlite3ParserTOKENTYPE yy0; - struct {int value; int mask;} yy47; - TriggerStep* yy91; - Token yy98; - Select* yy107; - struct TrigEvent yy146; - ExprList* yy210; - Expr* yy258; - SrcList* yy259; - IdList* yy272; - int yy284; - struct AttachKey yy292; - struct LikeOp yy342; - struct LimitVal yy404; - int yy449; + struct LikeOp yy30; + Select* yy91; + struct AttachKey yy92; + IdList* yy232; + struct {int value; int mask;} yy319; + ExprList* yy322; + int yy328; + struct TrigEvent yy378; + struct LimitVal yy388; + Expr* yy418; + Token yy430; + SrcList* yy439; + TriggerStep* yy451; + int yy485; } YYMINORTYPE; #define YYSTACKDEPTH 100 #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 537 -#define YYNRULE 292 -#define YYERRORSYMBOL 130 -#define YYERRSYMDT yy449 +#define YYNSTATE 569 +#define YYNRULE 309 +#define YYERRORSYMBOL 143 +#define YYERRSYMDT yy485 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -175,432 +175,481 @@ typedef union { ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 257, 325, 255, 138, 140, 142, 144, 146, 148, 150, - /* 10 */ 152, 154, 156, 345, 87, 88, 159, 12, 311, 310, - /* 20 */ 158, 146, 148, 150, 152, 154, 156, 813, 150, 152, - /* 30 */ 154, 156, 430, 50, 124, 112, 160, 169, 174, 179, - /* 40 */ 168, 173, 134, 136, 128, 130, 126, 132, 138, 140, - /* 50 */ 142, 144, 146, 148, 150, 152, 154, 156, 114, 439, - /* 60 */ 44, 256, 39, 58, 64, 66, 299, 330, 612, 293, - /* 70 */ 351, 223, 92, 332, 326, 159, 13, 14, 353, 158, - /* 80 */ 188, 355, 361, 366, 266, 12, 267, 259, 342, 87, - /* 90 */ 88, 12, 369, 124, 112, 160, 169, 174, 179, 168, - /* 100 */ 173, 134, 136, 128, 130, 126, 132, 138, 140, 142, - /* 110 */ 144, 146, 148, 150, 152, 154, 156, 297, 292, 349, - /* 120 */ 114, 183, 282, 185, 186, 403, 12, 31, 32, 225, - /* 130 */ 41, 255, 353, 269, 159, 355, 361, 366, 158, 166, - /* 140 */ 175, 180, 188, 286, 13, 14, 369, 92, 350, 382, - /* 150 */ 13, 14, 124, 112, 160, 169, 174, 179, 168, 173, - /* 160 */ 134, 136, 128, 130, 126, 132, 138, 140, 142, 144, - /* 170 */ 146, 148, 150, 152, 154, 156, 98, 96, 12, 159, - /* 180 */ 237, 98, 96, 158, 336, 13, 14, 337, 338, 265, - /* 190 */ 256, 225, 272, 807, 339, 515, 12, 124, 112, 160, - /* 200 */ 169, 174, 179, 168, 173, 134, 136, 128, 130, 126, - /* 210 */ 132, 138, 140, 142, 144, 146, 148, 150, 152, 154, - /* 220 */ 156, 128, 130, 126, 132, 138, 140, 142, 144, 146, - /* 230 */ 148, 150, 152, 154, 156, 5, 353, 13, 14, 355, - /* 240 */ 361, 366, 100, 87, 88, 92, 787, 697, 159, 349, - /* 250 */ 369, 815, 158, 542, 27, 13, 14, 383, 32, 518, - /* 260 */ 273, 546, 69, 247, 10, 765, 124, 112, 160, 169, - /* 270 */ 174, 179, 168, 173, 134, 136, 128, 130, 126, 132, - /* 280 */ 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, - /* 290 */ 73, 658, 12, 159, 269, 4, 6, 158, 56, 57, - /* 300 */ 24, 92, 274, 252, 513, 181, 488, 275, 407, 12, - /* 310 */ 8, 124, 112, 160, 169, 174, 179, 168, 173, 134, - /* 320 */ 136, 128, 130, 126, 132, 138, 140, 142, 144, 146, - /* 330 */ 148, 150, 152, 154, 156, 219, 73, 47, 547, 187, - /* 340 */ 763, 183, 514, 185, 186, 183, 48, 185, 186, 569, - /* 350 */ 464, 13, 14, 114, 114, 12, 114, 49, 516, 517, - /* 360 */ 45, 499, 288, 159, 545, 631, 287, 158, 13, 14, - /* 370 */ 46, 183, 480, 185, 186, 111, 474, 249, 474, 808, - /* 380 */ 205, 124, 112, 160, 169, 174, 179, 168, 173, 134, - /* 390 */ 136, 128, 130, 126, 132, 138, 140, 142, 144, 146, - /* 400 */ 148, 150, 152, 154, 156, 9, 780, 486, 159, 482, - /* 410 */ 103, 230, 158, 457, 13, 14, 92, 11, 470, 183, - /* 420 */ 506, 185, 186, 12, 50, 561, 124, 112, 160, 169, - /* 430 */ 174, 179, 168, 173, 134, 136, 128, 130, 126, 132, - /* 440 */ 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, - /* 450 */ 291, 36, 335, 39, 58, 64, 66, 299, 330, 183, - /* 460 */ 304, 185, 186, 537, 332, 304, 633, 159, 91, 87, - /* 470 */ 88, 158, 534, 535, 497, 810, 166, 175, 180, 368, - /* 480 */ 378, 484, 13, 14, 548, 124, 112, 160, 169, 174, - /* 490 */ 179, 168, 173, 134, 136, 128, 130, 126, 132, 138, - /* 500 */ 140, 142, 144, 146, 148, 150, 152, 154, 156, 441, - /* 510 */ 306, 659, 159, 244, 419, 306, 158, 418, 19, 183, - /* 520 */ 332, 185, 186, 623, 166, 175, 180, 92, 289, 420, - /* 530 */ 124, 112, 160, 169, 174, 179, 168, 173, 134, 136, - /* 540 */ 128, 130, 126, 132, 138, 140, 142, 144, 146, 148, - /* 550 */ 150, 152, 154, 156, 475, 447, 437, 159, 244, 438, - /* 560 */ 183, 158, 185, 186, 660, 77, 830, 1, 536, 3, - /* 570 */ 413, 415, 414, 553, 246, 124, 177, 160, 169, 174, - /* 580 */ 179, 168, 173, 134, 136, 128, 130, 126, 132, 138, - /* 590 */ 140, 142, 144, 146, 148, 150, 152, 154, 156, 245, - /* 600 */ 764, 691, 159, 89, 87, 88, 158, 269, 183, 41, - /* 610 */ 185, 186, 15, 16, 17, 388, 21, 452, 823, 246, - /* 620 */ 625, 112, 160, 169, 174, 179, 168, 173, 134, 136, - /* 630 */ 128, 130, 126, 132, 138, 140, 142, 144, 146, 148, - /* 640 */ 150, 152, 154, 156, 245, 77, 257, 159, 255, 227, - /* 650 */ 396, 158, 391, 380, 303, 527, 554, 422, 504, 325, - /* 660 */ 379, 72, 92, 417, 503, 68, 23, 160, 169, 174, - /* 670 */ 179, 168, 173, 134, 136, 128, 130, 126, 132, 138, - /* 680 */ 140, 142, 144, 146, 148, 150, 152, 154, 156, 207, - /* 690 */ 372, 72, 114, 77, 73, 68, 114, 387, 33, 189, - /* 700 */ 114, 348, 340, 182, 436, 402, 468, 256, 162, 203, - /* 710 */ 238, 215, 161, 555, 111, 195, 193, 294, 188, 207, - /* 720 */ 114, 660, 188, 191, 70, 71, 114, 433, 113, 189, - /* 730 */ 164, 165, 326, 73, 73, 227, 255, 307, 314, 316, - /* 740 */ 556, 501, 198, 436, 691, 195, 193, 72, 131, 312, - /* 750 */ 105, 68, 325, 191, 70, 71, 221, 163, 113, 460, - /* 760 */ 119, 120, 121, 122, 197, 773, 423, 225, 72, 313, - /* 770 */ 434, 224, 68, 73, 442, 207, 77, 47, 467, 444, - /* 780 */ 341, 325, 114, 363, 255, 189, 48, 25, 199, 74, - /* 790 */ 119, 120, 121, 122, 197, 256, 207, 49, 460, 114, - /* 800 */ 209, 195, 193, 283, 290, 114, 189, 28, 73, 191, - /* 810 */ 70, 71, 358, 446, 113, 457, 309, 114, 444, 73, - /* 820 */ 325, 194, 195, 193, 72, 326, 259, 133, 68, 51, - /* 830 */ 191, 70, 71, 529, 114, 113, 62, 35, 334, 206, - /* 840 */ 53, 29, 63, 256, 329, 259, 119, 120, 121, 122, - /* 850 */ 197, 319, 207, 238, 326, 222, 147, 223, 7, 114, - /* 860 */ 114, 277, 189, 18, 20, 22, 386, 119, 120, 121, - /* 870 */ 122, 197, 766, 114, 98, 96, 451, 521, 195, 193, - /* 880 */ 260, 135, 137, 531, 534, 535, 191, 70, 71, 114, - /* 890 */ 114, 113, 114, 326, 114, 204, 510, 34, 441, 114, - /* 900 */ 114, 267, 507, 508, 471, 402, 114, 114, 114, 114, - /* 910 */ 114, 139, 141, 114, 296, 114, 143, 114, 465, 560, - /* 920 */ 267, 176, 145, 119, 120, 121, 122, 197, 455, 196, - /* 930 */ 459, 149, 151, 114, 284, 178, 114, 220, 114, 153, - /* 940 */ 114, 487, 114, 489, 493, 437, 359, 416, 321, 479, - /* 950 */ 114, 402, 114, 114, 77, 155, 281, 473, 157, 471, - /* 960 */ 218, 611, 192, 30, 216, 402, 94, 95, 343, 114, - /* 970 */ 344, 803, 271, 395, 472, 239, 402, 114, 402, 242, - /* 980 */ 252, 411, 412, 114, 255, 99, 385, 481, 114, 43, - /* 990 */ 44, 234, 171, 184, 325, 802, 636, 114, 373, 408, - /* 1000 */ 321, 404, 114, 73, 402, 123, 114, 364, 90, 321, - /* 1010 */ 167, 320, 491, 321, 483, 240, 73, 2, 3, 190, - /* 1020 */ 26, 170, 384, 40, 367, 402, 114, 402, 125, 114, - /* 1030 */ 38, 79, 431, 37, 321, 41, 329, 42, 280, 52, - /* 1040 */ 428, 55, 59, 256, 54, 60, 67, 75, 127, 77, - /* 1050 */ 61, 129, 65, 570, 76, 571, 235, 238, 84, 78, - /* 1060 */ 101, 495, 80, 485, 81, 233, 102, 322, 86, 104, - /* 1070 */ 93, 97, 108, 107, 82, 109, 110, 115, 117, 83, - /* 1080 */ 172, 156, 85, 637, 638, 217, 639, 116, 202, 118, - /* 1090 */ 208, 211, 226, 210, 212, 213, 106, 214, 227, 236, - /* 1100 */ 241, 228, 231, 232, 229, 223, 243, 200, 251, 248, - /* 1110 */ 201, 250, 253, 258, 254, 270, 262, 261, 263, 264, - /* 1120 */ 268, 276, 278, 285, 295, 279, 298, 318, 301, 303, - /* 1130 */ 333, 300, 305, 323, 327, 346, 356, 357, 362, 370, - /* 1140 */ 371, 374, 53, 302, 354, 394, 331, 324, 308, 315, - /* 1150 */ 375, 401, 317, 347, 328, 389, 390, 392, 393, 409, - /* 1160 */ 397, 795, 398, 410, 421, 424, 360, 365, 800, 425, - /* 1170 */ 801, 381, 352, 377, 376, 400, 426, 427, 429, 771, - /* 1180 */ 772, 698, 399, 435, 432, 699, 443, 794, 445, 438, - /* 1190 */ 809, 449, 453, 450, 454, 440, 811, 458, 448, 462, - /* 1200 */ 461, 812, 463, 469, 477, 476, 814, 630, 456, 632, - /* 1210 */ 478, 779, 821, 490, 690, 492, 498, 494, 496, 693, - /* 1220 */ 696, 500, 509, 505, 781, 511, 782, 512, 783, 784, - /* 1230 */ 466, 785, 520, 502, 786, 519, 405, 523, 530, 525, - /* 1240 */ 524, 822, 406, 528, 824, 825, 533, 828, 518, 518, - /* 1250 */ 518, 518, 518, 518, 522, 518, 518, 518, 518, 518, - /* 1260 */ 526, 532, + /* 0 */ 263, 9, 261, 154, 124, 126, 128, 130, 132, 134, + /* 10 */ 136, 138, 140, 142, 406, 2, 145, 646, 4, 369, + /* 20 */ 144, 114, 116, 112, 118, 849, 124, 126, 128, 130, + /* 30 */ 132, 134, 136, 138, 140, 142, 136, 138, 140, 142, + /* 40 */ 110, 94, 146, 157, 162, 167, 156, 161, 120, 122, + /* 50 */ 114, 116, 112, 118, 572, 124, 126, 128, 130, 132, + /* 60 */ 134, 136, 138, 140, 142, 579, 223, 533, 262, 124, + /* 70 */ 126, 128, 130, 132, 134, 136, 138, 140, 142, 7, + /* 80 */ 96, 145, 13, 535, 536, 144, 442, 78, 371, 92, + /* 90 */ 453, 373, 380, 385, 132, 134, 136, 138, 140, 142, + /* 100 */ 75, 3, 567, 388, 296, 110, 94, 146, 157, 162, + /* 110 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, + /* 120 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + /* 130 */ 145, 10, 578, 13, 144, 11, 279, 569, 371, 6, + /* 140 */ 5, 373, 380, 385, 358, 25, 3, 567, 14, 15, + /* 150 */ 426, 507, 233, 388, 110, 94, 146, 157, 162, 167, + /* 160 */ 156, 161, 120, 122, 114, 116, 112, 118, 77, 124, + /* 170 */ 126, 128, 130, 132, 134, 136, 138, 140, 142, 577, + /* 180 */ 280, 258, 407, 77, 159, 281, 107, 106, 108, 107, + /* 190 */ 106, 108, 879, 1, 568, 172, 295, 4, 670, 14, + /* 200 */ 15, 371, 175, 145, 373, 380, 385, 144, 518, 343, + /* 210 */ 346, 16, 17, 18, 158, 367, 388, 415, 345, 410, + /* 220 */ 28, 345, 95, 402, 33, 95, 807, 110, 94, 146, + /* 230 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, + /* 240 */ 118, 51, 124, 126, 128, 130, 132, 134, 136, 138, + /* 250 */ 140, 142, 44, 45, 805, 101, 102, 103, 101, 102, + /* 260 */ 103, 852, 152, 222, 163, 168, 188, 261, 72, 37, + /* 270 */ 341, 40, 59, 67, 69, 305, 336, 145, 265, 36, + /* 280 */ 340, 144, 806, 338, 171, 13, 173, 174, 335, 27, + /* 290 */ 171, 403, 173, 174, 12, 460, 51, 313, 320, 322, + /* 300 */ 197, 110, 94, 146, 157, 162, 167, 156, 161, 120, + /* 310 */ 122, 114, 116, 112, 118, 288, 124, 126, 128, 130, + /* 320 */ 132, 134, 136, 138, 140, 142, 40, 59, 67, 69, + /* 330 */ 305, 336, 152, 262, 163, 168, 580, 263, 338, 261, + /* 340 */ 96, 145, 364, 362, 387, 144, 52, 170, 494, 466, + /* 350 */ 456, 14, 15, 645, 171, 31, 173, 174, 54, 81, + /* 360 */ 75, 331, 534, 601, 176, 110, 94, 146, 157, 162, + /* 370 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, + /* 380 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + /* 390 */ 152, 367, 163, 168, 325, 57, 58, 48, 297, 32, + /* 400 */ 33, 195, 213, 207, 96, 262, 49, 96, 26, 96, + /* 410 */ 13, 83, 96, 13, 217, 145, 265, 50, 286, 144, + /* 420 */ 46, 169, 368, 401, 75, 13, 367, 75, 176, 75, + /* 430 */ 47, 235, 75, 235, 565, 33, 176, 332, 211, 110, + /* 440 */ 94, 146, 157, 162, 167, 156, 161, 120, 122, 114, + /* 450 */ 116, 112, 118, 266, 124, 126, 128, 130, 132, 134, + /* 460 */ 136, 138, 140, 142, 303, 13, 298, 229, 227, 236, + /* 470 */ 96, 692, 292, 48, 243, 96, 14, 15, 217, 14, + /* 480 */ 15, 145, 49, 822, 278, 144, 217, 455, 13, 20, + /* 490 */ 75, 14, 15, 50, 190, 75, 201, 13, 65, 176, + /* 500 */ 13, 250, 593, 253, 66, 110, 94, 146, 157, 162, + /* 510 */ 167, 156, 161, 120, 122, 114, 116, 112, 118, 77, + /* 520 */ 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, + /* 530 */ 665, 14, 15, 693, 585, 250, 351, 356, 357, 871, + /* 540 */ 152, 191, 163, 168, 479, 628, 145, 327, 34, 216, + /* 550 */ 144, 366, 349, 22, 14, 15, 13, 331, 255, 171, + /* 560 */ 461, 173, 174, 14, 15, 463, 14, 15, 857, 252, + /* 570 */ 110, 94, 146, 157, 162, 167, 156, 161, 120, 122, + /* 580 */ 114, 116, 112, 118, 850, 124, 126, 128, 130, 132, + /* 590 */ 134, 136, 138, 140, 142, 251, 855, 273, 358, 187, + /* 600 */ 354, 356, 357, 252, 171, 310, 173, 174, 39, 42, + /* 610 */ 350, 399, 309, 145, 261, 829, 335, 144, 398, 455, + /* 620 */ 586, 294, 14, 15, 64, 293, 397, 667, 537, 251, + /* 630 */ 499, 77, 171, 328, 173, 174, 731, 110, 94, 146, + /* 640 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, + /* 650 */ 118, 77, 124, 126, 128, 130, 132, 134, 136, 138, + /* 660 */ 140, 142, 358, 312, 96, 505, 96, 501, 338, 96, + /* 670 */ 171, 96, 173, 174, 441, 845, 479, 24, 145, 532, + /* 680 */ 262, 275, 144, 331, 75, 214, 75, 215, 493, 75, + /* 690 */ 302, 75, 465, 493, 272, 91, 273, 463, 171, 694, + /* 700 */ 173, 174, 110, 94, 146, 157, 162, 167, 156, 161, + /* 710 */ 120, 122, 114, 116, 112, 118, 376, 124, 126, 128, + /* 720 */ 130, 132, 134, 136, 138, 140, 142, 587, 96, 171, + /* 730 */ 489, 173, 174, 96, 96, 525, 96, 246, 171, 271, + /* 740 */ 173, 174, 96, 145, 432, 434, 433, 144, 75, 503, + /* 750 */ 588, 452, 93, 75, 75, 348, 75, 109, 111, 332, + /* 760 */ 113, 265, 75, 342, 248, 258, 115, 110, 165, 146, + /* 770 */ 157, 162, 167, 156, 161, 120, 122, 114, 116, 112, + /* 780 */ 118, 29, 124, 126, 128, 130, 132, 134, 136, 138, + /* 790 */ 140, 142, 815, 96, 96, 96, 96, 299, 283, 215, + /* 800 */ 310, 96, 96, 96, 96, 364, 362, 219, 145, 317, + /* 810 */ 316, 275, 144, 75, 75, 75, 75, 117, 119, 121, + /* 820 */ 123, 75, 75, 75, 75, 125, 127, 129, 131, 352, + /* 830 */ 247, 353, 404, 94, 146, 157, 162, 167, 156, 161, + /* 840 */ 120, 122, 114, 116, 112, 118, 96, 124, 126, 128, + /* 850 */ 130, 132, 134, 136, 138, 140, 142, 96, 312, 96, + /* 860 */ 96, 331, 96, 331, 77, 96, 75, 96, 96, 436, + /* 870 */ 133, 30, 261, 96, 145, 96, 38, 75, 144, 75, + /* 880 */ 75, 135, 75, 137, 139, 75, 141, 75, 75, 143, + /* 890 */ 592, 153, 155, 75, 382, 75, 391, 164, 331, 166, + /* 900 */ 146, 157, 162, 167, 156, 161, 120, 122, 114, 116, + /* 910 */ 112, 118, 725, 124, 126, 128, 130, 132, 134, 136, + /* 920 */ 138, 140, 142, 76, 96, 96, 438, 71, 471, 437, + /* 930 */ 96, 449, 96, 96, 326, 96, 327, 332, 262, 332, + /* 940 */ 96, 439, 148, 42, 75, 75, 147, 35, 178, 180, + /* 950 */ 75, 199, 75, 75, 182, 75, 184, 196, 694, 198, + /* 960 */ 75, 107, 106, 108, 208, 430, 431, 177, 421, 657, + /* 970 */ 150, 151, 360, 361, 332, 96, 96, 548, 383, 421, + /* 980 */ 327, 96, 725, 318, 183, 181, 300, 96, 96, 450, + /* 990 */ 96, 327, 179, 73, 74, 75, 75, 95, 149, 210, + /* 1000 */ 212, 75, 290, 319, 96, 224, 558, 75, 75, 76, + /* 1010 */ 75, 240, 245, 71, 277, 275, 435, 423, 96, 96, + /* 1020 */ 96, 96, 75, 392, 75, 327, 287, 457, 386, 244, + /* 1030 */ 101, 102, 103, 104, 105, 185, 189, 199, 75, 75, + /* 1040 */ 75, 75, 427, 474, 478, 491, 694, 107, 106, 108, + /* 1050 */ 559, 219, 414, 177, 81, 484, 562, 273, 315, 486, + /* 1060 */ 219, 458, 45, 42, 492, 476, 490, 487, 421, 421, + /* 1070 */ 183, 181, 844, 483, 421, 421, 421, 421, 179, 73, + /* 1080 */ 74, 476, 81, 95, 77, 421, 526, 865, 490, 43, + /* 1090 */ 659, 77, 41, 53, 522, 523, 56, 55, 60, 244, + /* 1100 */ 61, 76, 81, 62, 64, 71, 500, 502, 70, 602, + /* 1110 */ 68, 63, 504, 506, 510, 514, 101, 102, 103, 104, + /* 1120 */ 105, 185, 189, 520, 546, 603, 77, 81, 470, 199, + /* 1130 */ 79, 80, 875, 244, 82, 239, 241, 84, 225, 107, + /* 1140 */ 106, 108, 85, 87, 516, 177, 86, 88, 90, 98, + /* 1150 */ 89, 97, 99, 100, 142, 160, 218, 671, 672, 673, + /* 1160 */ 186, 209, 183, 181, 194, 200, 203, 202, 192, 206, + /* 1170 */ 179, 73, 74, 204, 205, 95, 221, 193, 219, 220, + /* 1180 */ 226, 228, 232, 230, 231, 233, 242, 237, 234, 238, + /* 1190 */ 215, 249, 254, 76, 257, 260, 276, 71, 256, 259, + /* 1200 */ 264, 267, 269, 268, 270, 274, 282, 291, 101, 102, + /* 1210 */ 103, 104, 105, 185, 189, 808, 285, 301, 304, 306, + /* 1220 */ 284, 199, 324, 311, 355, 330, 307, 374, 308, 329, + /* 1230 */ 375, 107, 106, 108, 333, 309, 337, 177, 314, 334, + /* 1240 */ 372, 321, 344, 323, 378, 347, 381, 379, 365, 359, + /* 1250 */ 339, 389, 377, 400, 183, 181, 289, 384, 363, 390, + /* 1260 */ 370, 393, 179, 73, 74, 394, 395, 95, 54, 396, + /* 1270 */ 408, 409, 411, 412, 413, 416, 420, 417, 422, 76, + /* 1280 */ 428, 837, 429, 71, 443, 440, 444, 842, 843, 445, + /* 1290 */ 446, 447, 451, 448, 813, 454, 814, 459, 462, 732, + /* 1300 */ 101, 102, 103, 104, 105, 185, 189, 199, 836, 464, + /* 1310 */ 851, 457, 467, 418, 468, 733, 469, 107, 106, 108, + /* 1320 */ 424, 419, 475, 177, 473, 853, 472, 477, 425, 480, + /* 1330 */ 481, 482, 488, 485, 854, 495, 497, 856, 496, 664, + /* 1340 */ 183, 181, 666, 821, 863, 509, 511, 724, 179, 73, + /* 1350 */ 74, 513, 727, 95, 517, 515, 519, 730, 521, 524, + /* 1360 */ 8, 823, 528, 530, 824, 19, 21, 23, 405, 531, + /* 1370 */ 825, 826, 827, 539, 538, 828, 549, 542, 543, 540, + /* 1380 */ 541, 864, 544, 547, 866, 550, 101, 102, 103, 104, + /* 1390 */ 105, 185, 189, 545, 867, 552, 870, 872, 529, 557, + /* 1400 */ 460, 551, 555, 560, 554, 527, 873, 553, 561, 563, + /* 1410 */ 564, 566, 556, 874, 553, 553, 553, 553, 553, 553, + /* 1420 */ 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + /* 1430 */ 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + /* 1440 */ 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + /* 1450 */ 553, 553, 553, 508, 512, 456, 553, 553, 553, 498, + /* 1460 */ 553, 553, 553, 553, 81, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 24, 139, 26, 72, 73, 74, 75, 76, 77, 78, - /* 10 */ 79, 80, 81, 154, 155, 156, 40, 26, 88, 89, - /* 20 */ 44, 76, 77, 78, 79, 80, 81, 9, 78, 79, - /* 30 */ 80, 81, 170, 60, 58, 59, 60, 61, 62, 63, + /* 0 */ 24, 150, 26, 78, 79, 80, 81, 82, 83, 84, + /* 10 */ 85, 86, 87, 88, 155, 146, 40, 23, 149, 25, + /* 20 */ 44, 74, 75, 76, 77, 11, 79, 80, 81, 82, + /* 30 */ 83, 84, 85, 86, 87, 88, 85, 86, 87, 88, /* 40 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - /* 50 */ 74, 75, 76, 77, 78, 79, 80, 81, 139, 173, - /* 60 */ 174, 85, 89, 90, 91, 92, 93, 94, 23, 23, - /* 70 */ 25, 25, 213, 100, 212, 40, 85, 86, 87, 44, - /* 80 */ 161, 90, 91, 92, 23, 26, 25, 152, 154, 155, - /* 90 */ 156, 26, 101, 58, 59, 60, 61, 62, 63, 64, - /* 100 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 110 */ 75, 76, 77, 78, 79, 80, 81, 23, 199, 139, - /* 120 */ 139, 103, 187, 105, 106, 143, 26, 147, 148, 210, - /* 130 */ 95, 26, 87, 139, 40, 90, 91, 92, 44, 204, - /* 140 */ 205, 206, 161, 78, 85, 86, 101, 213, 168, 169, - /* 150 */ 85, 86, 58, 59, 60, 61, 62, 63, 64, 65, - /* 160 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - /* 170 */ 76, 77, 78, 79, 80, 81, 76, 77, 26, 40, - /* 180 */ 199, 76, 77, 44, 152, 85, 86, 155, 156, 195, - /* 190 */ 85, 210, 22, 11, 89, 95, 26, 58, 59, 60, - /* 200 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - /* 210 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - /* 220 */ 81, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 230 */ 77, 78, 79, 80, 81, 9, 87, 85, 86, 90, - /* 240 */ 91, 92, 154, 155, 156, 213, 9, 9, 40, 139, - /* 250 */ 101, 9, 44, 9, 144, 85, 86, 147, 148, 22, - /* 260 */ 146, 9, 22, 111, 12, 126, 58, 59, 60, 61, - /* 270 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 280 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 290 */ 176, 23, 26, 40, 139, 135, 136, 44, 13, 14, - /* 300 */ 140, 213, 188, 189, 67, 22, 146, 193, 126, 26, - /* 310 */ 137, 58, 59, 60, 61, 62, 63, 64, 65, 66, - /* 320 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 330 */ 77, 78, 79, 80, 81, 127, 176, 18, 9, 23, - /* 340 */ 17, 103, 139, 105, 106, 103, 27, 105, 106, 109, - /* 350 */ 195, 85, 86, 139, 139, 26, 139, 38, 155, 156, - /* 360 */ 41, 201, 104, 40, 9, 9, 108, 44, 85, 86, - /* 370 */ 51, 103, 20, 105, 106, 161, 161, 111, 161, 11, - /* 380 */ 127, 58, 59, 60, 61, 62, 63, 64, 65, 66, - /* 390 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 400 */ 77, 78, 79, 80, 81, 138, 9, 55, 40, 57, - /* 410 */ 196, 197, 44, 139, 85, 86, 213, 139, 203, 103, - /* 420 */ 203, 105, 106, 26, 60, 9, 58, 59, 60, 61, - /* 430 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - /* 440 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - /* 450 */ 23, 87, 88, 89, 90, 91, 92, 93, 94, 103, - /* 460 */ 45, 105, 106, 0, 100, 45, 9, 40, 154, 155, - /* 470 */ 156, 44, 9, 10, 200, 17, 204, 205, 206, 159, - /* 480 */ 60, 129, 85, 86, 9, 58, 59, 60, 61, 62, - /* 490 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - /* 500 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 51, - /* 510 */ 95, 23, 40, 25, 28, 95, 44, 31, 138, 103, - /* 520 */ 100, 105, 106, 9, 204, 205, 206, 213, 23, 43, - /* 530 */ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - /* 540 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - /* 550 */ 78, 79, 80, 81, 96, 97, 98, 40, 25, 58, - /* 560 */ 103, 44, 105, 106, 24, 107, 131, 132, 133, 134, - /* 570 */ 96, 97, 98, 9, 86, 58, 59, 60, 61, 62, - /* 580 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - /* 590 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 111, - /* 600 */ 17, 9, 40, 154, 155, 156, 44, 139, 103, 95, - /* 610 */ 105, 106, 13, 14, 15, 20, 138, 25, 9, 86, - /* 620 */ 119, 59, 60, 61, 62, 63, 64, 65, 66, 67, - /* 630 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - /* 640 */ 78, 79, 80, 81, 111, 107, 24, 40, 26, 109, - /* 650 */ 55, 44, 57, 164, 165, 46, 9, 21, 120, 139, - /* 660 */ 171, 22, 213, 195, 146, 26, 138, 60, 61, 62, - /* 670 */ 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - /* 680 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 50, - /* 690 */ 170, 22, 139, 107, 176, 26, 139, 142, 149, 60, - /* 700 */ 139, 152, 153, 146, 146, 139, 120, 85, 40, 126, - /* 710 */ 118, 128, 44, 9, 161, 76, 77, 78, 161, 50, - /* 720 */ 139, 95, 161, 84, 85, 86, 139, 91, 89, 60, - /* 730 */ 62, 63, 212, 176, 176, 109, 26, 96, 97, 98, - /* 740 */ 9, 175, 161, 146, 9, 76, 77, 22, 161, 32, - /* 750 */ 197, 26, 139, 84, 85, 86, 199, 89, 89, 201, - /* 760 */ 121, 122, 123, 124, 125, 129, 211, 210, 22, 52, - /* 770 */ 215, 210, 26, 176, 216, 50, 107, 18, 146, 221, - /* 780 */ 22, 139, 139, 170, 26, 60, 27, 141, 207, 146, - /* 790 */ 121, 122, 123, 124, 125, 85, 50, 38, 201, 139, - /* 800 */ 41, 76, 77, 78, 161, 139, 60, 145, 176, 84, - /* 810 */ 85, 86, 170, 216, 89, 139, 99, 139, 221, 176, - /* 820 */ 139, 161, 76, 77, 22, 212, 152, 161, 26, 89, - /* 830 */ 84, 85, 86, 123, 139, 89, 29, 157, 158, 161, - /* 840 */ 100, 23, 35, 85, 164, 152, 121, 122, 123, 124, - /* 850 */ 125, 170, 50, 118, 212, 23, 161, 25, 11, 139, - /* 860 */ 139, 187, 60, 16, 17, 18, 19, 121, 122, 123, - /* 870 */ 124, 125, 126, 139, 76, 77, 200, 30, 76, 77, - /* 880 */ 187, 161, 161, 36, 9, 10, 84, 85, 86, 139, - /* 890 */ 139, 89, 139, 212, 139, 161, 49, 150, 51, 139, - /* 900 */ 139, 25, 23, 56, 25, 139, 139, 139, 139, 139, - /* 910 */ 139, 161, 161, 139, 161, 139, 161, 139, 23, 9, - /* 920 */ 25, 161, 161, 121, 122, 123, 124, 125, 161, 161, - /* 930 */ 161, 161, 161, 139, 139, 161, 139, 161, 139, 161, - /* 940 */ 139, 175, 139, 96, 97, 98, 23, 47, 25, 102, - /* 950 */ 139, 139, 139, 139, 107, 161, 161, 23, 161, 25, - /* 960 */ 161, 23, 161, 25, 161, 139, 121, 122, 23, 139, - /* 970 */ 25, 95, 161, 146, 161, 161, 139, 139, 139, 188, - /* 980 */ 189, 53, 54, 139, 26, 25, 146, 175, 139, 173, - /* 990 */ 174, 161, 60, 104, 139, 95, 107, 139, 23, 161, - /* 1000 */ 25, 175, 139, 176, 139, 161, 139, 23, 48, 25, - /* 1010 */ 161, 23, 175, 25, 175, 25, 176, 133, 134, 161, - /* 1020 */ 22, 89, 24, 159, 161, 139, 139, 139, 161, 139, - /* 1030 */ 158, 179, 23, 139, 25, 95, 164, 33, 186, 159, - /* 1040 */ 175, 42, 46, 85, 167, 160, 22, 177, 161, 107, - /* 1050 */ 159, 161, 159, 109, 176, 109, 115, 118, 184, 178, - /* 1060 */ 113, 175, 180, 175, 181, 116, 114, 212, 117, 25, - /* 1070 */ 214, 214, 94, 160, 182, 26, 151, 109, 109, 183, - /* 1080 */ 89, 81, 185, 107, 107, 126, 107, 139, 17, 139, - /* 1090 */ 22, 174, 139, 23, 25, 139, 198, 23, 109, 114, - /* 1100 */ 110, 139, 198, 160, 143, 25, 190, 208, 111, 139, - /* 1110 */ 209, 139, 139, 139, 143, 95, 192, 191, 112, 22, - /* 1120 */ 139, 23, 191, 109, 23, 192, 159, 22, 162, 165, - /* 1130 */ 167, 139, 139, 198, 198, 23, 46, 22, 22, 46, - /* 1140 */ 22, 93, 100, 163, 139, 24, 151, 160, 166, 166, - /* 1150 */ 139, 95, 166, 152, 160, 139, 143, 139, 143, 39, - /* 1160 */ 139, 11, 143, 37, 47, 129, 159, 159, 95, 139, - /* 1170 */ 95, 169, 169, 163, 162, 218, 143, 95, 22, 9, - /* 1180 */ 129, 119, 217, 11, 159, 119, 17, 9, 9, 58, - /* 1190 */ 17, 139, 139, 99, 67, 172, 9, 67, 172, 139, - /* 1200 */ 119, 9, 22, 22, 139, 110, 9, 9, 181, 9, - /* 1210 */ 181, 9, 9, 110, 9, 181, 181, 172, 99, 9, - /* 1220 */ 9, 119, 139, 22, 9, 139, 9, 143, 9, 9, - /* 1230 */ 202, 9, 23, 202, 9, 139, 219, 152, 34, 139, - /* 1240 */ 24, 9, 220, 152, 9, 9, 139, 9, 224, 224, - /* 1250 */ 224, 224, 224, 224, 222, 224, 224, 224, 224, 224, - /* 1260 */ 223, 222, + /* 50 */ 74, 75, 76, 77, 9, 79, 80, 81, 82, 83, + /* 60 */ 84, 85, 86, 87, 88, 9, 25, 152, 92, 79, + /* 70 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 9, + /* 80 */ 152, 40, 26, 168, 169, 44, 227, 159, 94, 48, + /* 90 */ 231, 97, 98, 99, 83, 84, 85, 86, 87, 88, + /* 100 */ 172, 9, 10, 109, 176, 64, 65, 66, 67, 68, + /* 110 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 191, + /* 120 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 130 */ 40, 151, 9, 26, 44, 12, 159, 0, 94, 147, + /* 140 */ 148, 97, 98, 99, 229, 153, 9, 10, 92, 93, + /* 150 */ 136, 159, 26, 109, 64, 65, 66, 67, 68, 69, + /* 160 */ 70, 71, 72, 73, 74, 75, 76, 77, 191, 79, + /* 170 */ 80, 81, 82, 83, 84, 85, 86, 87, 88, 9, + /* 180 */ 203, 204, 20, 191, 66, 208, 60, 61, 62, 60, + /* 190 */ 61, 62, 144, 145, 146, 112, 23, 149, 115, 92, + /* 200 */ 93, 94, 23, 40, 97, 98, 99, 44, 216, 83, + /* 210 */ 84, 13, 14, 15, 96, 152, 109, 55, 92, 57, + /* 220 */ 157, 92, 96, 160, 161, 96, 136, 64, 65, 66, + /* 230 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 240 */ 77, 66, 79, 80, 81, 82, 83, 84, 85, 86, + /* 250 */ 87, 88, 188, 189, 17, 129, 130, 131, 129, 130, + /* 260 */ 131, 17, 219, 220, 221, 222, 23, 26, 22, 94, + /* 270 */ 95, 96, 97, 98, 99, 100, 101, 40, 165, 170, + /* 280 */ 171, 44, 17, 108, 111, 26, 113, 114, 179, 22, + /* 290 */ 111, 24, 113, 114, 152, 51, 66, 104, 105, 106, + /* 300 */ 137, 64, 65, 66, 67, 68, 69, 70, 71, 72, + /* 310 */ 73, 74, 75, 76, 77, 202, 79, 80, 81, 82, + /* 320 */ 83, 84, 85, 86, 87, 88, 96, 97, 98, 99, + /* 330 */ 100, 101, 219, 92, 221, 222, 9, 24, 108, 26, + /* 340 */ 152, 40, 83, 84, 173, 44, 96, 159, 104, 105, + /* 350 */ 106, 92, 93, 23, 111, 25, 113, 114, 108, 115, + /* 360 */ 172, 152, 103, 117, 176, 64, 65, 66, 67, 68, + /* 370 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 191, + /* 380 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 390 */ 219, 152, 221, 222, 185, 13, 14, 18, 23, 160, + /* 400 */ 161, 136, 214, 138, 152, 92, 27, 152, 154, 152, + /* 410 */ 26, 194, 152, 26, 226, 40, 165, 38, 201, 44, + /* 420 */ 41, 22, 183, 184, 172, 26, 152, 172, 176, 172, + /* 430 */ 51, 176, 172, 176, 160, 161, 176, 228, 137, 64, + /* 440 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + /* 450 */ 75, 76, 77, 202, 79, 80, 81, 82, 83, 84, + /* 460 */ 85, 86, 87, 88, 23, 26, 214, 212, 211, 212, + /* 470 */ 152, 23, 85, 18, 214, 152, 92, 93, 226, 92, + /* 480 */ 93, 40, 27, 9, 22, 44, 226, 159, 26, 151, + /* 490 */ 172, 92, 93, 38, 176, 172, 41, 26, 29, 176, + /* 500 */ 26, 25, 9, 119, 35, 64, 65, 66, 67, 68, + /* 510 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 191, + /* 520 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + /* 530 */ 9, 92, 93, 23, 9, 25, 167, 168, 169, 9, + /* 540 */ 219, 223, 221, 222, 216, 23, 40, 25, 162, 226, + /* 550 */ 44, 165, 166, 151, 92, 93, 26, 152, 119, 111, + /* 560 */ 232, 113, 114, 92, 93, 237, 92, 93, 9, 93, + /* 570 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + /* 580 */ 74, 75, 76, 77, 11, 79, 80, 81, 82, 83, + /* 590 */ 84, 85, 86, 87, 88, 119, 9, 25, 229, 159, + /* 600 */ 167, 168, 169, 93, 111, 45, 113, 114, 171, 103, + /* 610 */ 22, 179, 180, 40, 26, 9, 179, 44, 186, 159, + /* 620 */ 9, 112, 92, 93, 102, 116, 66, 9, 22, 119, + /* 630 */ 20, 191, 111, 228, 113, 114, 9, 64, 65, 66, + /* 640 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 650 */ 77, 191, 79, 80, 81, 82, 83, 84, 85, 86, + /* 660 */ 87, 88, 229, 103, 152, 55, 152, 57, 108, 152, + /* 670 */ 111, 152, 113, 114, 21, 103, 216, 151, 40, 73, + /* 680 */ 92, 152, 44, 152, 172, 23, 172, 25, 176, 172, + /* 690 */ 176, 172, 232, 176, 23, 176, 25, 237, 111, 9, + /* 700 */ 113, 114, 64, 65, 66, 67, 68, 69, 70, 71, + /* 710 */ 72, 73, 74, 75, 76, 77, 185, 79, 80, 81, + /* 720 */ 82, 83, 84, 85, 86, 87, 88, 9, 152, 111, + /* 730 */ 218, 113, 114, 152, 152, 218, 152, 25, 111, 210, + /* 740 */ 113, 114, 152, 40, 104, 105, 106, 44, 172, 139, + /* 750 */ 9, 98, 176, 172, 172, 164, 172, 176, 176, 228, + /* 760 */ 176, 165, 172, 172, 203, 204, 176, 64, 65, 66, + /* 770 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 780 */ 77, 158, 79, 80, 81, 82, 83, 84, 85, 86, + /* 790 */ 87, 88, 139, 152, 152, 152, 152, 23, 202, 25, + /* 800 */ 45, 152, 152, 152, 152, 83, 84, 117, 40, 95, + /* 810 */ 96, 152, 44, 172, 172, 172, 172, 176, 176, 176, + /* 820 */ 176, 172, 172, 172, 172, 176, 176, 176, 176, 23, + /* 830 */ 118, 25, 159, 65, 66, 67, 68, 69, 70, 71, + /* 840 */ 72, 73, 74, 75, 76, 77, 152, 79, 80, 81, + /* 850 */ 82, 83, 84, 85, 86, 87, 88, 152, 103, 152, + /* 860 */ 152, 152, 152, 152, 191, 152, 172, 152, 152, 210, + /* 870 */ 176, 23, 26, 152, 40, 152, 152, 172, 44, 172, + /* 880 */ 172, 176, 172, 176, 176, 172, 176, 172, 172, 176, + /* 890 */ 9, 176, 176, 172, 185, 172, 185, 176, 152, 176, + /* 900 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + /* 910 */ 76, 77, 9, 79, 80, 81, 82, 83, 84, 85, + /* 920 */ 86, 87, 88, 22, 152, 152, 28, 26, 25, 31, + /* 930 */ 152, 185, 152, 152, 23, 152, 25, 228, 92, 228, + /* 940 */ 152, 43, 40, 103, 172, 172, 44, 163, 176, 176, + /* 950 */ 172, 50, 172, 172, 176, 172, 176, 176, 24, 176, + /* 960 */ 172, 60, 61, 62, 176, 53, 54, 66, 152, 9, + /* 970 */ 68, 69, 129, 130, 228, 152, 152, 131, 23, 152, + /* 980 */ 25, 152, 9, 32, 83, 84, 85, 152, 152, 23, + /* 990 */ 152, 25, 91, 92, 93, 172, 172, 96, 96, 176, + /* 1000 */ 176, 172, 152, 52, 152, 176, 190, 172, 172, 22, + /* 1010 */ 172, 176, 176, 26, 176, 152, 47, 190, 152, 152, + /* 1020 */ 152, 152, 172, 23, 172, 25, 176, 64, 176, 126, + /* 1030 */ 129, 130, 131, 132, 133, 134, 135, 50, 172, 172, + /* 1040 */ 172, 172, 176, 176, 176, 176, 103, 60, 61, 62, + /* 1050 */ 59, 117, 159, 66, 115, 23, 240, 25, 107, 159, + /* 1060 */ 117, 188, 189, 103, 23, 152, 25, 128, 152, 152, + /* 1070 */ 83, 84, 103, 210, 152, 152, 152, 152, 91, 92, + /* 1080 */ 93, 152, 115, 96, 191, 152, 23, 9, 25, 33, + /* 1090 */ 127, 191, 173, 173, 159, 128, 42, 182, 46, 126, + /* 1100 */ 174, 22, 115, 173, 102, 26, 190, 190, 22, 117, + /* 1110 */ 173, 175, 190, 190, 190, 190, 129, 130, 131, 132, + /* 1120 */ 133, 134, 135, 190, 46, 117, 191, 115, 215, 50, + /* 1130 */ 192, 191, 141, 126, 193, 124, 123, 195, 121, 60, + /* 1140 */ 61, 62, 196, 198, 215, 66, 197, 199, 125, 152, + /* 1150 */ 200, 117, 117, 152, 88, 96, 152, 115, 115, 115, + /* 1160 */ 22, 136, 83, 84, 17, 22, 189, 23, 224, 23, + /* 1170 */ 91, 92, 93, 25, 152, 96, 156, 225, 117, 152, + /* 1180 */ 122, 25, 101, 213, 174, 26, 122, 213, 164, 174, + /* 1190 */ 25, 205, 152, 22, 119, 156, 103, 26, 152, 152, + /* 1200 */ 152, 206, 120, 207, 22, 152, 23, 117, 129, 130, + /* 1210 */ 131, 132, 133, 134, 135, 136, 207, 23, 173, 152, + /* 1220 */ 206, 50, 22, 152, 23, 174, 177, 46, 178, 213, + /* 1230 */ 22, 60, 61, 62, 213, 180, 164, 66, 181, 174, + /* 1240 */ 152, 181, 172, 181, 23, 172, 22, 173, 165, 230, + /* 1250 */ 182, 46, 175, 184, 83, 84, 85, 173, 230, 22, + /* 1260 */ 184, 100, 91, 92, 93, 152, 177, 96, 108, 178, + /* 1270 */ 152, 156, 152, 156, 24, 152, 103, 156, 156, 22, + /* 1280 */ 39, 11, 37, 26, 139, 47, 152, 103, 103, 156, + /* 1290 */ 103, 152, 173, 22, 9, 11, 139, 187, 17, 127, + /* 1300 */ 129, 130, 131, 132, 133, 134, 135, 50, 9, 9, + /* 1310 */ 17, 64, 187, 233, 152, 127, 107, 60, 61, 62, + /* 1320 */ 235, 234, 196, 66, 73, 9, 152, 73, 236, 127, + /* 1330 */ 152, 22, 22, 217, 9, 118, 196, 9, 152, 9, + /* 1340 */ 83, 84, 9, 9, 9, 118, 196, 9, 91, 92, + /* 1350 */ 93, 187, 9, 96, 196, 107, 127, 9, 217, 22, + /* 1360 */ 11, 9, 152, 152, 9, 16, 17, 18, 19, 156, + /* 1370 */ 9, 9, 9, 23, 152, 9, 34, 165, 24, 30, + /* 1380 */ 238, 9, 152, 165, 9, 36, 129, 130, 131, 132, + /* 1390 */ 133, 134, 135, 239, 9, 152, 9, 9, 49, 20, + /* 1400 */ 51, 238, 156, 140, 152, 56, 9, 58, 152, 141, + /* 1410 */ 241, 142, 63, 9, 242, 242, 242, 242, 242, 242, + /* 1420 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + /* 1430 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + /* 1440 */ 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + /* 1450 */ 242, 242, 242, 104, 105, 106, 242, 242, 242, 110, + /* 1460 */ 242, 242, 242, 242, 115, }; -#define YY_SHIFT_USE_DFLT (-71) +#define YY_SHIFT_USE_DFLT (-76) static const short yy_shift_ofst[] = { - /* 0 */ 875, 463, -71, 847, 226, -71, 244, 599, 252, 355, - /* 10 */ 329, 475, -71, -71, -71, -71, -71, -71, 252, 564, - /* 20 */ 252, 647, 252, 704, 998, 731, 59, 938, 818, 910, - /* 30 */ -9, -71, 958, -71, 364, -71, 59, -27, -71, 940, - /* 40 */ -71, 1004, 319, -71, -71, -71, -71, -71, -71, -71, - /* 50 */ 740, 940, -71, 999, -71, 285, -71, -71, 996, 807, - /* 60 */ 940, -71, -71, -71, 940, -71, 1024, 802, 240, 639, - /* 70 */ 944, 946, 669, -71, 505, 942, -71, 258, -71, 990, - /* 80 */ 939, 941, 949, 947, 951, -71, 798, -71, -71, 960, - /* 90 */ 798, -71, 845, -71, -71, -71, 845, -71, -71, 798, - /* 100 */ -71, 952, 802, 1044, 802, 978, 807, -71, 1049, -71, - /* 110 */ -71, 472, 802, -71, 968, 59, 969, 59, -71, -71, - /* 120 */ -71, -71, -71, 607, 802, 562, 802, -69, 802, -69, - /* 130 */ 802, -69, 802, -69, 802, 153, 802, 153, 802, -55, - /* 140 */ 802, -55, 802, -55, 802, -55, 802, -50, 802, -50, - /* 150 */ 802, 1000, 802, 1000, 802, 1000, 802, -71, -71, -71, - /* 160 */ 668, -71, -71, -71, -71, -71, 802, 153, -71, 932, - /* 170 */ -71, 991, -71, -71, -71, 802, 517, 802, 153, -71, - /* 180 */ 283, 669, 316, 889, 976, 977, 979, -71, 472, 802, - /* 190 */ 607, 802, -71, 802, -71, 802, -71, 746, 139, 959, - /* 200 */ 583, 1071, -71, 802, 253, 802, 472, 1068, 759, 1070, - /* 210 */ -71, 1069, 59, 1074, -71, 802, 323, 802, 208, 802, - /* 220 */ 472, 832, -71, 802, -71, -71, 989, 59, -71, -71, - /* 230 */ 978, 807, -71, 802, 472, 985, 802, 1080, 802, 472, - /* 240 */ -71, -71, 533, -71, -71, -71, 152, -71, 266, -71, - /* 250 */ 997, -71, 170, 989, 622, -71, -71, 59, -71, -71, - /* 260 */ 1020, 1006, -71, 1097, 59, 61, -71, 59, -71, -71, - /* 270 */ 802, 472, 942, 268, 488, 1098, 622, 1020, 1006, -71, - /* 280 */ 725, -24, -71, -71, 1014, 65, -71, -71, -71, -71, - /* 290 */ 427, -71, 46, -71, 1101, -71, 94, 940, -71, 59, - /* 300 */ 1105, -71, 415, -71, 59, -71, 641, 717, -71, -70, - /* 310 */ -71, -71, -71, -71, 717, -71, 717, -71, 59, 988, - /* 320 */ -71, 59, 978, 807, -71, -71, 978, 807, -71, -71, - /* 330 */ 1049, -71, 999, -71, -71, 105, -71, -71, -71, -71, - /* 340 */ 758, 798, 945, -71, 798, 1112, -71, -71, -71, -71, - /* 350 */ 45, 149, -71, 59, -71, 1090, 1115, 59, 923, 940, - /* 360 */ -71, 1116, 59, 984, 940, -71, 802, 35, -71, 1093, - /* 370 */ 1118, 59, 975, 1048, 59, 1105, -71, 420, 1042, -71, - /* 380 */ -71, -71, -71, -71, 942, 416, 636, 595, 59, 989, - /* 390 */ -71, 59, 540, 1121, 942, 356, 59, 989, 486, 474, - /* 400 */ 1056, 59, 989, -71, 1120, 182, 1150, 802, 368, 1126, - /* 410 */ 928, -71, -71, 1073, 1075, 900, 59, 876, -71, -71, - /* 420 */ 1117, -71, -71, 1036, 59, 626, 1082, 59, 1156, 59, - /* 430 */ 1009, 514, 1170, 1051, 1172, 458, 242, 501, 319, -71, - /* 440 */ 1062, 1066, 1169, 1178, 1179, 458, 1173, 1131, 59, 1094, - /* 450 */ 59, 592, 59, 1127, 802, 472, 1187, 1130, 802, 472, - /* 460 */ 1081, 59, 1180, 59, 895, -71, 586, 18, 1181, 802, - /* 470 */ 934, 802, 472, 1192, 472, 1095, 59, 735, 1197, 352, - /* 480 */ 59, 1198, 59, 1200, 59, 1202, 59, 1203, 457, 1103, - /* 490 */ 59, 735, 1205, 1131, 59, 1119, 59, 592, 1210, 1102, - /* 500 */ 59, 1180, 538, 238, 1201, 802, 879, 1211, 397, 1215, - /* 510 */ 59, 989, 237, 100, 1217, 1219, 1220, 1222, 59, 1209, - /* 520 */ 1225, 1204, 958, 1216, 59, 609, 1232, 710, 1235, 1236, - /* 530 */ -71, 1204, 59, 1238, -71, -71, -71, + /* 0 */ 92, 137, -76, -76, 1349, 45, 70, -76, 198, 123, + /* 10 */ 170, 56, 327, -76, -76, -76, -76, -76, -76, 123, + /* 20 */ 525, 123, 611, 123, 718, 267, 741, 471, 330, 848, + /* 30 */ 881, 107, -76, 241, -76, 175, -76, 471, 230, -76, + /* 40 */ 840, -76, 1056, 379, -76, -76, -76, -76, -76, -76, + /* 50 */ -76, 250, 840, -76, 1054, -76, 382, -76, -76, 1052, + /* 60 */ 469, 840, 1002, -76, -76, -76, -76, 840, -76, 1086, + /* 70 */ 1257, 246, 901, 992, 1008, -76, 987, -76, 173, 1012, + /* 80 */ -76, 509, -76, 712, 1007, 1013, 1011, 1017, 1023, -76, + /* 90 */ 1257, 41, 1257, 638, 1257, -76, 1034, 471, 1035, 471, + /* 100 */ -76, -76, -76, -76, -76, -76, -76, -76, -76, 834, + /* 110 */ 1257, 768, 1257, -10, 1257, -10, 1257, -10, 1257, -10, + /* 120 */ 1257, -53, 1257, -53, 1257, 11, 1257, 11, 1257, 11, + /* 130 */ 1257, 11, 1257, -49, 1257, -49, 1257, 1066, 1257, 1066, + /* 140 */ 1257, 1066, 1257, -76, -76, -76, 902, -76, -76, -76, + /* 150 */ -76, -76, 1257, -75, 1257, -10, -76, 118, -76, 1059, + /* 160 */ -76, -76, -76, 1257, 703, 1257, -53, -76, 399, 987, + /* 170 */ 179, 83, 1042, 1043, 1044, -76, 638, 1257, 834, 1257, + /* 180 */ -76, 1257, -76, 1257, -76, 1138, 1012, 243, -76, 1079, + /* 190 */ 90, 1025, 265, 1147, -76, 1257, 163, 1257, 638, 1143, + /* 200 */ 455, 1144, -76, 1148, 471, 1146, -76, 1257, 237, 1257, + /* 210 */ 301, 1257, 638, 662, -76, 1257, -76, -76, 1061, 471, + /* 220 */ -76, -76, -76, 1257, 638, 1058, 1257, 1156, 1257, 1081, + /* 230 */ 469, -76, 1159, -76, -76, 638, 1081, 469, -76, 1257, + /* 240 */ 638, 1064, 1257, 1165, 1257, 638, -76, -76, 476, -76, + /* 250 */ -76, -76, 384, -76, 439, -76, 1075, -76, 462, 1061, + /* 260 */ 313, -76, -76, 471, -76, -76, 1093, 1082, -76, 1182, + /* 270 */ 471, 671, -76, 471, -76, -76, 1257, 638, 1012, 448, + /* 280 */ 510, 1183, 313, 1093, 1082, -76, 1171, -24, -76, -76, + /* 290 */ 1090, 387, -76, -76, -76, -76, 375, -76, 774, -76, + /* 300 */ 1194, -76, 441, 840, -76, 471, 1200, -76, 755, -76, + /* 310 */ 471, -76, 193, 951, -76, 714, -76, -76, -76, -76, + /* 320 */ 951, -76, 951, -76, 471, 911, -76, 471, 1081, 469, + /* 330 */ -76, -76, 1081, 469, -76, -76, 1159, -76, 1054, -76, + /* 340 */ -76, 126, -76, 129, -76, -76, 129, -76, -76, 588, + /* 350 */ 722, 806, -76, 722, 1201, -76, -76, -76, 843, -76, + /* 360 */ -76, -76, 843, -76, -76, -76, -76, -76, -6, 44, + /* 370 */ -76, 471, -76, 1181, 1208, 471, 522, 1221, 840, -76, + /* 380 */ 1224, 471, 955, 840, -76, 1257, 506, -76, 1205, 1237, + /* 390 */ 471, 1000, 1161, 471, 1200, -76, 560, 1160, -76, -76, + /* 400 */ -76, -76, -76, 1012, 493, 653, 162, 471, 1061, -76, + /* 410 */ 471, 934, 1250, 1012, 521, 471, 1061, 898, 640, 1173, + /* 420 */ 471, 1061, -76, 1241, 14, 1270, 1257, 573, 1245, 912, + /* 430 */ -76, -76, 1184, 1185, 969, 471, 572, -76, -76, 1238, + /* 440 */ -76, -76, 1145, 471, 943, 1187, 471, 1271, 471, 966, + /* 450 */ 960, 1285, 1157, 1284, 244, 559, 963, 379, -76, 1172, + /* 460 */ 1188, 1281, 1299, 1300, 244, 1293, 1247, 471, 1209, 471, + /* 470 */ 903, 471, 1251, 1257, 638, 1316, 1254, 1257, 638, 1202, + /* 480 */ 471, 1309, 471, 1032, -76, 939, 587, 1310, 1257, 1041, + /* 490 */ 1257, 638, 1325, 638, 1217, 471, 973, 1328, 610, 471, + /* 500 */ 1330, 471, 1333, 471, 1334, 471, 1335, 618, 1227, 471, + /* 510 */ 973, 1338, 1247, 471, 1248, 471, 903, 1343, 1229, 471, + /* 520 */ 1309, 967, 627, 1337, 1257, 1063, 1348, 474, 1352, 471, + /* 530 */ 1061, 606, 259, 1355, 1361, 1362, 1363, 471, 1350, 1366, + /* 540 */ 1342, 241, 1354, 471, 1078, 1372, 846, 1375, 1385, -76, + /* 550 */ 1342, 471, 1387, 530, 690, 1388, 1379, 471, 991, 1263, + /* 560 */ 471, 1397, 1268, 1269, 471, 1404, -76, -76, -76, }; -#define YY_REDUCE_USE_DFLT (-142) +#define YY_REDUCE_USE_DFLT (-150) static const short yy_reduce_ofst[] = { - /* 0 */ 435, 884, -142, 160, -142, -142, -142, 173, 267, -142, - /* 10 */ 278, -142, -142, -142, -142, -142, -142, -142, 380, -142, - /* 20 */ 478, -142, 528, -142, 646, -142, 110, 662, -142, -142, - /* 30 */ -20, -142, 549, 747, 680, -142, 894, 872, -142, 864, - /* 40 */ -142, -142, 816, -142, -142, -142, -142, -142, -142, -142, - /* 50 */ -142, 880, -142, 877, -142, -142, -142, -142, -142, 885, - /* 60 */ 891, -142, -142, -142, 893, -142, -142, 753, -142, -81, - /* 70 */ -142, -142, 643, -142, 870, 878, -142, 881, 852, 882, - /* 80 */ 883, 892, 896, 874, 897, -142, 449, -142, -142, -142, - /* 90 */ 314, -142, 856, -142, -142, -142, 857, -142, -142, 88, - /* 100 */ -142, -142, 214, -142, 553, 898, 913, -142, 925, -142, - /* 110 */ -142, 272, 844, -142, -142, 948, -142, 950, -142, -142, - /* 120 */ -142, -142, -142, 272, 867, 272, 887, 272, 890, 272, - /* 130 */ 587, 272, 666, 272, 720, 272, 721, 272, 750, 272, - /* 140 */ 751, 272, 755, 272, 761, 272, 695, 272, 770, 272, - /* 150 */ 771, 272, 778, 272, 794, 272, 797, 272, -142, -142, - /* 160 */ -142, -142, -142, -142, -142, -142, 849, 272, -142, -142, - /* 170 */ -142, -142, -142, -142, -142, 760, 272, 774, 272, -142, - /* 180 */ 953, 557, 870, -142, -142, -142, -142, -142, 272, 858, - /* 190 */ 272, 801, 272, 660, 272, 768, 272, 581, 272, 899, - /* 200 */ 901, -142, -142, 734, 272, 678, 272, -142, 917, -142, - /* 210 */ -142, -142, 956, -142, -142, 803, 272, 799, 272, 776, - /* 220 */ 272, -142, -142, 561, -142, -142, 961, 962, -142, -142, - /* 230 */ 904, 943, -142, 830, 272, -142, -19, -142, 814, 272, - /* 240 */ -142, 791, 916, -142, -142, -142, 970, -142, 972, -142, - /* 250 */ -142, -142, 973, 971, 693, -142, -142, 974, -142, -142, - /* 260 */ 926, 924, -142, -142, -6, -142, -142, 981, -142, -142, - /* 270 */ 811, 272, 114, 870, 916, -142, 674, 931, 933, -142, - /* 280 */ 795, -65, -142, -142, -142, 948, -142, -142, -142, -142, - /* 290 */ 272, -142, -142, -142, -142, -142, 272, 967, -142, 992, - /* 300 */ 966, 980, 964, -142, 993, -142, -142, 982, -142, -142, - /* 310 */ -142, -142, -142, -142, 983, -142, 986, -142, 681, -142, - /* 320 */ -142, 855, 935, 987, -142, -142, 936, 994, -142, -142, - /* 330 */ 995, -142, 963, -142, -142, 32, -142, -142, -142, -142, - /* 340 */ 1001, -66, -142, -142, -141, -142, -142, -142, -142, -142, - /* 350 */ 1002, 1003, -142, 1005, -142, -142, -142, 642, -142, 1007, - /* 360 */ -142, -142, 613, -142, 1008, -142, 863, 320, -142, -142, - /* 370 */ -142, 520, -142, -142, 1011, 1012, 1010, 489, -142, -142, - /* 380 */ -142, -142, -142, -142, 840, 870, 555, -142, 1016, 1013, - /* 390 */ -142, 1018, 1015, -142, 827, 870, 1021, 1019, 965, 957, - /* 400 */ -142, 826, -18, -142, 1017, 1022, -142, 838, 272, -142, - /* 410 */ -142, -142, -142, -142, -142, -142, 468, -142, -142, -142, - /* 420 */ -142, -142, -142, -142, 1030, 1033, -142, 865, -142, -138, - /* 430 */ -142, 1025, -142, -142, -142, 558, 870, 1023, -114, -142, - /* 440 */ -142, -142, -142, -142, -142, 597, -142, 1026, 1052, -142, - /* 450 */ 676, 1027, 1053, -142, 767, 272, -142, -142, 769, 272, - /* 460 */ -142, 1060, 1028, 155, -142, -142, 632, 870, -142, 215, - /* 470 */ -142, 813, 272, -142, 272, -142, 1065, 1029, -142, -142, - /* 480 */ 812, -142, 839, -142, 888, -142, 766, -142, 870, -142, - /* 490 */ 837, 1034, -142, 1045, 886, -142, 274, 1035, -142, -142, - /* 500 */ 566, 1031, 518, 870, -142, 217, -142, -142, 1083, -142, - /* 510 */ 1086, 1084, -142, 203, -142, -142, -142, -142, 1096, -142, - /* 520 */ -142, 1032, 1085, -142, 1100, 1037, -142, 1091, -142, -142, - /* 530 */ -142, 1039, 1107, -142, -142, -142, -142, + /* 0 */ 48, -131, -150, -150, -8, -150, -150, -150, -149, -20, + /* 10 */ -150, 142, -150, -150, -150, -150, -150, -150, -150, 338, + /* 20 */ -150, 402, -150, 526, -150, 254, -150, 63, 623, -150, + /* 30 */ -150, 239, -150, 386, 784, 109, -150, 724, 437, -150, + /* 40 */ 919, -150, -150, 64, -150, -150, -150, -150, -150, -150, + /* 50 */ -150, -150, 920, -150, 915, -150, -150, -150, -150, -150, + /* 60 */ 926, 930, 936, -150, -150, -150, -150, 937, -150, -150, + /* 70 */ 514, -150, 252, -150, -150, -150, -72, -150, 938, 940, + /* 80 */ -150, 941, 217, 942, 946, 949, 945, 948, 950, -150, + /* 90 */ 519, 321, 576, 321, 581, -150, -150, 997, -150, 1001, + /* 100 */ -150, -150, -150, -150, -150, -150, -150, -150, -150, 321, + /* 110 */ 582, 321, 584, 321, 590, 321, 641, 321, 642, 321, + /* 120 */ 643, 321, 644, 321, 649, 321, 650, 321, 651, 321, + /* 130 */ 652, 321, 694, 321, 705, 321, 707, 321, 708, 321, + /* 140 */ 710, 321, 713, 321, -150, -150, -150, -150, -150, -150, + /* 150 */ -150, -150, 715, 43, 716, 321, -150, -150, -150, -150, + /* 160 */ -150, -150, -150, 721, 321, 723, 321, -150, 1004, 188, + /* 170 */ 938, -150, -150, -150, -150, -150, 321, 772, 321, 773, + /* 180 */ 321, 778, 321, 780, 321, -150, 440, 938, -150, 318, + /* 190 */ 321, 944, 952, -150, -150, 781, 321, 783, 321, -150, + /* 200 */ 977, -150, -150, -150, 1022, -150, -150, 788, 321, 823, + /* 210 */ 321, 824, 321, -150, -150, 323, -150, -150, 1020, 1027, + /* 220 */ -150, -150, -150, 829, 321, -150, 257, -150, 255, 970, + /* 230 */ 1010, -150, 1024, -150, -150, 321, 974, 1015, -150, 835, + /* 240 */ 321, -150, 260, -150, 836, 321, -150, 561, 986, -150, + /* 250 */ -150, -150, 1040, -150, 1046, -150, -150, -150, 1047, 1039, + /* 260 */ 251, -150, -150, 1048, -150, -150, 995, 996, -150, -150, + /* 270 */ 529, -150, -150, 1053, -150, -150, 838, 321, -23, 938, + /* 280 */ 986, -150, 596, 1014, 1009, -150, 850, 113, -150, -150, + /* 290 */ -150, 997, -150, -150, -150, -150, 321, -150, -150, -150, + /* 300 */ -150, -150, 321, 1045, -150, 1067, 1049, 1050, 1055, -150, + /* 310 */ 1071, -150, -150, 1057, -150, -150, -150, -150, -150, -150, + /* 320 */ 1060, -150, 1062, -150, 209, -150, -150, 405, 1016, 1051, + /* 330 */ -150, -150, 1021, 1065, -150, -150, 1072, -150, 1068, -150, + /* 340 */ -150, 591, -150, 1070, -150, -150, 1073, -150, -150, 1083, + /* 350 */ 369, -150, -150, 433, -150, -150, -150, -150, 1019, -150, + /* 360 */ -150, -150, 1028, -150, -150, -150, -150, -150, 1069, 1076, + /* 370 */ -150, 1088, -150, -150, -150, 531, 1077, -150, 1074, -150, + /* 380 */ -150, 709, -150, 1084, -150, 852, 171, -150, -150, -150, + /* 390 */ 711, -150, -150, 1113, 1089, 1091, 432, -150, -150, -150, + /* 400 */ -150, -150, -150, 673, 938, -141, -150, 1118, 1115, -150, + /* 410 */ 1120, 1117, -150, 893, 938, 1123, 1121, 1080, 1087, -150, + /* 420 */ 827, 1122, -150, 1085, 1092, -150, 866, 321, -150, -150, + /* 430 */ -150, -150, -150, -150, -150, 659, -150, -150, -150, -150, + /* 440 */ -150, -150, -150, 1134, 1133, -150, 1139, -150, 746, -150, + /* 450 */ 1119, -150, -150, -150, 328, 938, 1110, 873, -150, -150, + /* 460 */ -150, -150, -150, -150, 460, -150, 1125, 1162, -150, 913, + /* 470 */ 1126, 1174, -150, 867, 321, -150, -150, 868, 321, -150, + /* 480 */ 1178, 1116, 863, -150, -150, 900, 938, -150, 512, -150, + /* 490 */ 869, 321, -150, 321, -150, 1186, 1140, -150, -150, 916, + /* 500 */ -150, 917, -150, 922, -150, 923, -150, 938, -150, 924, + /* 510 */ 1150, -150, 1164, 925, -150, 929, 1158, -150, -150, 933, + /* 520 */ 1141, 935, 938, -150, 517, -150, -150, 1210, -150, 1211, + /* 530 */ 1213, -150, -85, -150, -150, -150, -150, 1222, -150, -150, + /* 540 */ 1142, 1212, -150, 1230, 1154, -150, 1218, -150, -150, -150, + /* 550 */ 1163, 1243, -150, 1252, 1246, -150, -150, 816, -150, -150, + /* 560 */ 1256, -150, -150, 1169, 274, -150, -150, -150, -150, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 544, 544, 538, 829, 829, 540, 829, 549, 829, 829, - /* 10 */ 829, 829, 569, 570, 571, 550, 551, 552, 829, 829, - /* 20 */ 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, - /* 30 */ 829, 562, 572, 581, 564, 580, 829, 829, 582, 623, - /* 40 */ 588, 829, 829, 624, 627, 628, 629, 818, 819, 820, - /* 50 */ 829, 623, 589, 608, 606, 829, 609, 610, 829, 679, - /* 60 */ 623, 590, 677, 678, 623, 591, 829, 829, 708, 770, - /* 70 */ 714, 709, 829, 634, 829, 829, 635, 643, 645, 652, - /* 80 */ 691, 682, 684, 672, 686, 640, 793, 578, 579, 687, - /* 90 */ 793, 688, 829, 788, 790, 791, 829, 789, 792, 793, - /* 100 */ 689, 829, 829, 673, 829, 680, 679, 674, 829, 566, - /* 110 */ 681, 676, 829, 707, 829, 829, 710, 829, 711, 712, - /* 120 */ 713, 715, 716, 719, 829, 720, 829, 721, 829, 722, - /* 130 */ 829, 723, 829, 724, 829, 725, 829, 726, 829, 727, - /* 140 */ 829, 728, 829, 729, 829, 730, 829, 731, 829, 732, - /* 150 */ 829, 733, 829, 734, 829, 735, 829, 736, 737, 738, - /* 160 */ 829, 739, 740, 745, 753, 756, 829, 741, 742, 829, - /* 170 */ 743, 829, 746, 744, 752, 829, 829, 829, 754, 755, - /* 180 */ 829, 770, 829, 829, 829, 829, 829, 758, 769, 829, - /* 190 */ 747, 829, 748, 829, 749, 829, 750, 829, 829, 829, - /* 200 */ 829, 829, 760, 829, 829, 829, 761, 829, 829, 829, - /* 210 */ 816, 829, 829, 829, 817, 829, 829, 829, 829, 829, - /* 220 */ 762, 829, 757, 770, 767, 768, 660, 829, 661, 759, - /* 230 */ 680, 679, 675, 829, 685, 829, 770, 683, 829, 692, - /* 240 */ 644, 655, 653, 654, 663, 664, 829, 665, 829, 666, - /* 250 */ 829, 667, 829, 660, 651, 567, 568, 829, 649, 650, - /* 260 */ 669, 671, 656, 829, 829, 829, 670, 829, 704, 705, - /* 270 */ 829, 668, 655, 829, 829, 829, 651, 669, 671, 657, - /* 280 */ 829, 651, 646, 647, 829, 829, 648, 641, 642, 751, - /* 290 */ 829, 706, 829, 717, 829, 718, 829, 623, 592, 829, - /* 300 */ 774, 596, 593, 597, 829, 598, 829, 829, 599, 829, - /* 310 */ 602, 603, 604, 605, 829, 600, 829, 601, 829, 829, - /* 320 */ 775, 829, 680, 679, 776, 778, 680, 679, 777, 594, - /* 330 */ 829, 595, 608, 607, 583, 793, 584, 585, 586, 587, - /* 340 */ 573, 793, 829, 574, 793, 829, 575, 577, 576, 565, - /* 350 */ 829, 829, 613, 829, 616, 829, 829, 829, 829, 623, - /* 360 */ 617, 829, 829, 829, 623, 618, 829, 623, 619, 829, - /* 370 */ 829, 829, 829, 829, 829, 774, 596, 621, 829, 620, - /* 380 */ 622, 614, 615, 563, 829, 829, 559, 829, 829, 660, - /* 390 */ 557, 829, 829, 829, 829, 829, 829, 660, 799, 829, - /* 400 */ 829, 829, 660, 662, 804, 829, 829, 829, 829, 829, - /* 410 */ 829, 805, 806, 829, 829, 829, 829, 829, 796, 797, - /* 420 */ 829, 798, 558, 829, 829, 829, 829, 829, 829, 829, - /* 430 */ 829, 829, 829, 829, 829, 829, 829, 829, 829, 626, - /* 440 */ 829, 829, 829, 829, 829, 829, 829, 625, 829, 829, - /* 450 */ 829, 829, 829, 829, 829, 694, 829, 829, 829, 695, - /* 460 */ 829, 829, 702, 829, 829, 703, 829, 829, 829, 829, - /* 470 */ 829, 829, 700, 829, 701, 829, 829, 829, 829, 829, - /* 480 */ 829, 829, 829, 829, 829, 829, 829, 829, 829, 829, - /* 490 */ 829, 829, 829, 625, 829, 829, 829, 829, 829, 829, - /* 500 */ 829, 702, 829, 829, 829, 829, 829, 829, 829, 829, - /* 510 */ 829, 660, 829, 793, 829, 829, 829, 829, 829, 829, - /* 520 */ 829, 827, 829, 829, 829, 829, 829, 829, 829, 829, - /* 530 */ 826, 827, 829, 829, 541, 543, 539, + /* 0 */ 575, 575, 570, 573, 878, 878, 878, 574, 581, 878, + /* 10 */ 878, 878, 878, 601, 602, 603, 582, 583, 584, 878, + /* 20 */ 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, + /* 30 */ 878, 878, 594, 604, 613, 596, 612, 878, 878, 614, + /* 40 */ 657, 620, 878, 878, 658, 661, 662, 663, 860, 861, + /* 50 */ 862, 878, 657, 621, 642, 640, 878, 643, 644, 878, + /* 60 */ 713, 657, 628, 622, 629, 711, 712, 657, 623, 878, + /* 70 */ 878, 743, 812, 749, 744, 740, 878, 668, 878, 878, + /* 80 */ 669, 677, 679, 686, 725, 716, 718, 706, 720, 674, + /* 90 */ 878, 721, 878, 722, 878, 742, 878, 878, 745, 878, + /* 100 */ 746, 747, 748, 750, 751, 752, 755, 756, 757, 758, + /* 110 */ 878, 759, 878, 760, 878, 761, 878, 762, 878, 763, + /* 120 */ 878, 764, 878, 765, 878, 766, 878, 767, 878, 768, + /* 130 */ 878, 769, 878, 770, 878, 771, 878, 772, 878, 773, + /* 140 */ 878, 774, 878, 775, 776, 777, 878, 778, 779, 786, + /* 150 */ 793, 796, 878, 781, 878, 780, 783, 878, 784, 878, + /* 160 */ 787, 785, 792, 878, 878, 878, 794, 795, 878, 812, + /* 170 */ 878, 878, 878, 878, 878, 799, 811, 878, 788, 878, + /* 180 */ 789, 878, 790, 878, 791, 878, 878, 878, 801, 878, + /* 190 */ 878, 878, 878, 878, 802, 878, 878, 878, 803, 878, + /* 200 */ 878, 878, 858, 878, 878, 878, 859, 878, 878, 878, + /* 210 */ 878, 878, 804, 878, 797, 812, 809, 810, 694, 878, + /* 220 */ 695, 800, 782, 878, 723, 878, 878, 707, 878, 714, + /* 230 */ 713, 708, 878, 598, 715, 710, 714, 713, 709, 878, + /* 240 */ 719, 878, 812, 717, 878, 726, 678, 689, 687, 688, + /* 250 */ 697, 698, 878, 699, 878, 700, 878, 701, 878, 694, + /* 260 */ 685, 599, 600, 878, 683, 684, 703, 705, 690, 878, + /* 270 */ 878, 878, 704, 878, 738, 739, 878, 702, 689, 878, + /* 280 */ 878, 878, 685, 703, 705, 691, 878, 685, 680, 681, + /* 290 */ 878, 878, 682, 675, 676, 798, 878, 741, 878, 753, + /* 300 */ 878, 754, 878, 657, 624, 878, 816, 630, 625, 631, + /* 310 */ 878, 632, 878, 878, 633, 878, 636, 637, 638, 639, + /* 320 */ 878, 634, 878, 635, 878, 878, 817, 878, 714, 713, + /* 330 */ 818, 820, 714, 713, 819, 626, 878, 627, 642, 641, + /* 340 */ 615, 878, 616, 878, 617, 749, 878, 618, 619, 605, + /* 350 */ 835, 878, 606, 835, 878, 607, 610, 611, 878, 830, + /* 360 */ 832, 833, 878, 831, 834, 609, 608, 597, 878, 878, + /* 370 */ 647, 878, 650, 878, 878, 878, 878, 878, 657, 651, + /* 380 */ 878, 878, 878, 657, 652, 878, 657, 653, 878, 878, + /* 390 */ 878, 878, 878, 878, 816, 630, 655, 878, 654, 656, + /* 400 */ 648, 649, 595, 878, 878, 591, 878, 878, 694, 589, + /* 410 */ 878, 878, 878, 878, 878, 878, 694, 841, 878, 878, + /* 420 */ 878, 694, 696, 846, 878, 878, 878, 878, 878, 878, + /* 430 */ 847, 848, 878, 878, 878, 878, 878, 838, 839, 878, + /* 440 */ 840, 590, 878, 878, 878, 878, 878, 878, 878, 878, + /* 450 */ 878, 878, 878, 878, 878, 878, 878, 878, 660, 878, + /* 460 */ 878, 878, 878, 878, 878, 878, 659, 878, 878, 878, + /* 470 */ 878, 878, 878, 878, 728, 878, 878, 878, 729, 878, + /* 480 */ 878, 736, 878, 878, 737, 878, 878, 878, 878, 878, + /* 490 */ 878, 734, 878, 735, 878, 878, 878, 878, 878, 878, + /* 500 */ 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, + /* 510 */ 878, 878, 659, 878, 878, 878, 878, 878, 878, 878, + /* 520 */ 736, 878, 878, 878, 878, 878, 878, 878, 878, 878, + /* 530 */ 694, 878, 835, 878, 878, 878, 878, 878, 878, 878, + /* 540 */ 869, 878, 878, 878, 878, 878, 878, 878, 878, 868, + /* 550 */ 869, 878, 878, 878, 878, 878, 878, 878, 878, 878, + /* 560 */ 878, 878, 878, 876, 878, 878, 877, 576, 571, }; #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) @@ -674,6 +723,12 @@ static const YYCODETYPE yyFallback[] = { 26, /* TRIGGER => ID */ 26, /* VACUUM => ID */ 26, /* VIEW => ID */ + 26, /* REINDEX => ID */ + 26, /* RENAME => ID */ + 26, /* CDATE => ID */ + 26, /* CTIME => ID */ + 26, /* CTIMESTAMP => ID */ + 26, /* ALTER => ID */ 0, /* OR => nothing */ 0, /* AND => nothing */ 0, /* NOT => nothing */ @@ -688,6 +743,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* LE => nothing */ 0, /* LT => nothing */ 0, /* GE => nothing */ + 0, /* ESCAPE => nothing */ 0, /* BITAND => nothing */ 0, /* BITOR => nothing */ 0, /* LSHIFT => nothing */ @@ -711,6 +767,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* CHECK => nothing */ 0, /* REFERENCES => nothing */ 0, /* COLLATE => nothing */ + 0, /* AUTOINCR => nothing */ 0, /* ON => nothing */ 0, /* DELETE => nothing */ 0, /* UPDATE => nothing */ @@ -740,12 +797,17 @@ static const YYCODETYPE yyFallback[] = { 0, /* INTEGER => nothing */ 0, /* FLOAT => nothing */ 0, /* BLOB => nothing */ + 0, /* REGISTER => nothing */ 0, /* VARIABLE => nothing */ + 0, /* EXISTS => nothing */ 0, /* CASE => nothing */ 0, /* WHEN => nothing */ 0, /* THEN => nothing */ 0, /* ELSE => nothing */ 0, /* INDEX => nothing */ + 0, /* TO => nothing */ + 0, /* ADD => nothing */ + 0, /* COLUMNKW => nothing */ }; #endif /* YYFALLBACK */ @@ -830,16 +892,18 @@ static const char *const yyTokenName[] = { "LIKE", "MATCH", "KEY", "OF", "OFFSET", "PRAGMA", "RAISE", "REPLACE", "RESTRICT", "ROW", "STATEMENT", "TRIGGER", - "VACUUM", "VIEW", "OR", "AND", - "NOT", "IS", "BETWEEN", "IN", - "ISNULL", "NOTNULL", "NE", "EQ", - "GT", "LE", "LT", "GE", - "BITAND", "BITOR", "LSHIFT", "RSHIFT", - "PLUS", "MINUS", "STAR", "SLASH", - "REM", "CONCAT", "UMINUS", "UPLUS", - "BITNOT", "STRING", "JOIN_KW", "CONSTRAINT", - "DEFAULT", "NULL", "PRIMARY", "UNIQUE", - "CHECK", "REFERENCES", "COLLATE", "ON", + "VACUUM", "VIEW", "REINDEX", "RENAME", + "CDATE", "CTIME", "CTIMESTAMP", "ALTER", + "OR", "AND", "NOT", "IS", + "BETWEEN", "IN", "ISNULL", "NOTNULL", + "NE", "EQ", "GT", "LE", + "LT", "GE", "ESCAPE", "BITAND", + "BITOR", "LSHIFT", "RSHIFT", "PLUS", + "MINUS", "STAR", "SLASH", "REM", + "CONCAT", "UMINUS", "UPLUS", "BITNOT", + "STRING", "JOIN_KW", "CONSTRAINT", "DEFAULT", + "NULL", "PRIMARY", "UNIQUE", "CHECK", + "REFERENCES", "COLLATE", "AUTOINCR", "ON", "DELETE", "UPDATE", "INSERT", "SET", "DEFERRABLE", "FOREIGN", "DROP", "UNION", "ALL", "INTERSECT", "EXCEPT", "SELECT", @@ -847,31 +911,34 @@ static const char *const yyTokenName[] = { "USING", "ORDER", "BY", "GROUP", "HAVING", "LIMIT", "WHERE", "INTO", "VALUES", "INTEGER", "FLOAT", "BLOB", - "VARIABLE", "CASE", "WHEN", "THEN", - "ELSE", "INDEX", "error", "input", - "cmdlist", "ecmd", "explain", "cmdx", - "cmd", "transtype", "trans_opt", "nm", - "create_table", "create_table_args", "temp", "dbnm", - "columnlist", "conslist_opt", "select", "column", - "columnid", "type", "carglist", "id", - "ids", "typename", "signed", "plus_num", - "minus_num", "carg", "ccons", "onconf", - "sortorder", "expr", "idxlist_opt", "refargs", - "defer_subclause", "refarg", "refact", "init_deferred_pred_opt", - "conslist", "tcons", "idxlist", "defer_subclause_opt", - "orconf", "resolvetype", "raisetype", "fullname", - "oneselect", "multiselect_op", "distinct", "selcollist", - "from", "where_opt", "groupby_opt", "having_opt", - "orderby_opt", "limit_opt", "sclp", "as", - "seltablist", "stl_prefix", "joinop", "on_opt", - "using_opt", "seltablist_paren", "joinop2", "inscollist", - "sortlist", "sortitem", "collate", "exprlist", - "setlist", "insert_cmd", "inscollist_opt", "itemlist", - "likeop", "between_op", "in_op", "case_operand", + "REGISTER", "VARIABLE", "EXISTS", "CASE", + "WHEN", "THEN", "ELSE", "INDEX", + "TO", "ADD", "COLUMNKW", "error", + "input", "cmdlist", "ecmd", "cmdx", + "cmd", "explain", "transtype", "trans_opt", + "nm", "create_table", "create_table_args", "temp", + "dbnm", "columnlist", "conslist_opt", "select", + "column", "columnid", "type", "carglist", + "id", "ids", "typename", "signed", + "plus_num", "minus_num", "carg", "ccons", + "term", "onconf", "sortorder", "autoinc", + "expr", "idxlist_opt", "refargs", "defer_subclause", + "refarg", "refact", "init_deferred_pred_opt", "conslist", + "tcons", "idxlist", "defer_subclause_opt", "orconf", + "resolvetype", "raisetype", "fullname", "oneselect", + "multiselect_op", "distinct", "selcollist", "from", + "where_opt", "groupby_opt", "having_opt", "orderby_opt", + "limit_opt", "sclp", "as", "seltablist", + "stl_prefix", "joinop", "on_opt", "using_opt", + "seltablist_paren", "joinop2", "inscollist", "sortlist", + "sortitem", "collate", "exprlist", "setlist", + "insert_cmd", "inscollist_opt", "itemlist", "likeop", + "escape", "between_op", "in_op", "case_operand", "case_exprlist", "case_else", "expritem", "uniqueflag", "idxitem", "plus_opt", "number", "trigger_decl", "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", "when_clause", "trigger_cmd", "database_kw_opt", "key_opt", + "add_column_fullname", "kwcolumn_opt", }; #endif /* NDEBUG */ @@ -882,11 +949,11 @@ static const char *const yyRuleName[] = { /* 0 */ "input ::= cmdlist", /* 1 */ "cmdlist ::= cmdlist ecmd", /* 2 */ "cmdlist ::= ecmd", - /* 3 */ "ecmd ::= explain cmdx SEMI", + /* 3 */ "cmdx ::= cmd", /* 4 */ "ecmd ::= SEMI", - /* 5 */ "cmdx ::= cmd", - /* 6 */ "explain ::= EXPLAIN", - /* 7 */ "explain ::=", + /* 5 */ "ecmd ::= explain cmdx SEMI", + /* 6 */ "explain ::=", + /* 7 */ "explain ::= EXPLAIN", /* 8 */ "cmd ::= BEGIN transtype trans_opt", /* 9 */ "trans_opt ::=", /* 10 */ "trans_opt ::= TRANSACTION", @@ -926,251 +993,268 @@ static const char *const yyRuleName[] = { /* 44 */ "carglist ::=", /* 45 */ "carg ::= CONSTRAINT nm ccons", /* 46 */ "carg ::= ccons", - /* 47 */ "carg ::= DEFAULT ids", - /* 48 */ "carg ::= DEFAULT plus_num", - /* 49 */ "carg ::= DEFAULT minus_num", - /* 50 */ "carg ::= DEFAULT NULL", + /* 47 */ "carg ::= DEFAULT term", + /* 48 */ "carg ::= DEFAULT PLUS term", + /* 49 */ "carg ::= DEFAULT MINUS term", + /* 50 */ "carg ::= DEFAULT id", /* 51 */ "ccons ::= NULL onconf", /* 52 */ "ccons ::= NOT NULL onconf", - /* 53 */ "ccons ::= PRIMARY KEY sortorder onconf", + /* 53 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", /* 54 */ "ccons ::= UNIQUE onconf", /* 55 */ "ccons ::= CHECK LP expr RP onconf", /* 56 */ "ccons ::= REFERENCES nm idxlist_opt refargs", /* 57 */ "ccons ::= defer_subclause", /* 58 */ "ccons ::= COLLATE id", - /* 59 */ "refargs ::=", - /* 60 */ "refargs ::= refargs refarg", - /* 61 */ "refarg ::= MATCH nm", - /* 62 */ "refarg ::= ON DELETE refact", - /* 63 */ "refarg ::= ON UPDATE refact", - /* 64 */ "refarg ::= ON INSERT refact", - /* 65 */ "refact ::= SET NULL", - /* 66 */ "refact ::= SET DEFAULT", - /* 67 */ "refact ::= CASCADE", - /* 68 */ "refact ::= RESTRICT", - /* 69 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", - /* 70 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", - /* 71 */ "init_deferred_pred_opt ::=", - /* 72 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", - /* 73 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", - /* 74 */ "conslist_opt ::=", - /* 75 */ "conslist_opt ::= COMMA conslist", - /* 76 */ "conslist ::= conslist COMMA tcons", - /* 77 */ "conslist ::= conslist tcons", - /* 78 */ "conslist ::= tcons", - /* 79 */ "tcons ::= CONSTRAINT nm", - /* 80 */ "tcons ::= PRIMARY KEY LP idxlist RP onconf", - /* 81 */ "tcons ::= UNIQUE LP idxlist RP onconf", - /* 82 */ "tcons ::= CHECK expr onconf", - /* 83 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", - /* 84 */ "defer_subclause_opt ::=", - /* 85 */ "defer_subclause_opt ::= defer_subclause", - /* 86 */ "onconf ::=", - /* 87 */ "onconf ::= ON CONFLICT resolvetype", - /* 88 */ "orconf ::=", - /* 89 */ "orconf ::= OR resolvetype", - /* 90 */ "resolvetype ::= raisetype", - /* 91 */ "resolvetype ::= IGNORE", - /* 92 */ "resolvetype ::= REPLACE", - /* 93 */ "cmd ::= DROP TABLE fullname", - /* 94 */ "cmd ::= CREATE temp VIEW nm dbnm AS select", - /* 95 */ "cmd ::= DROP VIEW fullname", - /* 96 */ "cmd ::= select", - /* 97 */ "select ::= oneselect", - /* 98 */ "select ::= select multiselect_op oneselect", - /* 99 */ "multiselect_op ::= UNION", - /* 100 */ "multiselect_op ::= UNION ALL", - /* 101 */ "multiselect_op ::= INTERSECT", - /* 102 */ "multiselect_op ::= EXCEPT", - /* 103 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 104 */ "distinct ::= DISTINCT", - /* 105 */ "distinct ::= ALL", - /* 106 */ "distinct ::=", - /* 107 */ "sclp ::= selcollist COMMA", - /* 108 */ "sclp ::=", - /* 109 */ "selcollist ::= sclp expr as", - /* 110 */ "selcollist ::= sclp STAR", - /* 111 */ "selcollist ::= sclp nm DOT STAR", - /* 112 */ "as ::= AS nm", - /* 113 */ "as ::= ids", - /* 114 */ "as ::=", - /* 115 */ "from ::=", - /* 116 */ "from ::= FROM seltablist", - /* 117 */ "stl_prefix ::= seltablist joinop", - /* 118 */ "stl_prefix ::=", - /* 119 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt", - /* 120 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt", - /* 121 */ "seltablist_paren ::= select", - /* 122 */ "seltablist_paren ::= seltablist", - /* 123 */ "dbnm ::=", - /* 124 */ "dbnm ::= DOT nm", - /* 125 */ "fullname ::= nm dbnm", - /* 126 */ "joinop ::= COMMA", - /* 127 */ "joinop ::= JOIN", - /* 128 */ "joinop ::= JOIN_KW JOIN", - /* 129 */ "joinop ::= JOIN_KW nm JOIN", - /* 130 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 131 */ "on_opt ::= ON expr", - /* 132 */ "on_opt ::=", - /* 133 */ "using_opt ::= USING LP inscollist RP", - /* 134 */ "using_opt ::=", - /* 135 */ "orderby_opt ::=", - /* 136 */ "orderby_opt ::= ORDER BY sortlist", - /* 137 */ "sortlist ::= sortlist COMMA sortitem collate sortorder", - /* 138 */ "sortlist ::= sortitem collate sortorder", - /* 139 */ "sortitem ::= expr", - /* 140 */ "sortorder ::= ASC", - /* 141 */ "sortorder ::= DESC", - /* 142 */ "sortorder ::=", - /* 143 */ "collate ::=", - /* 144 */ "collate ::= COLLATE id", - /* 145 */ "groupby_opt ::=", - /* 146 */ "groupby_opt ::= GROUP BY exprlist", - /* 147 */ "having_opt ::=", - /* 148 */ "having_opt ::= HAVING expr", - /* 149 */ "limit_opt ::=", - /* 150 */ "limit_opt ::= LIMIT signed", - /* 151 */ "limit_opt ::= LIMIT signed OFFSET signed", - /* 152 */ "limit_opt ::= LIMIT signed COMMA signed", - /* 153 */ "cmd ::= DELETE FROM fullname where_opt", - /* 154 */ "where_opt ::=", - /* 155 */ "where_opt ::= WHERE expr", - /* 156 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", - /* 157 */ "setlist ::= setlist COMMA nm EQ expr", - /* 158 */ "setlist ::= nm EQ expr", - /* 159 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", - /* 160 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", - /* 161 */ "insert_cmd ::= INSERT orconf", - /* 162 */ "insert_cmd ::= REPLACE", - /* 163 */ "itemlist ::= itemlist COMMA expr", - /* 164 */ "itemlist ::= expr", - /* 165 */ "inscollist_opt ::=", - /* 166 */ "inscollist_opt ::= LP inscollist RP", - /* 167 */ "inscollist ::= inscollist COMMA nm", - /* 168 */ "inscollist ::= nm", - /* 169 */ "expr ::= LP expr RP", - /* 170 */ "expr ::= NULL", - /* 171 */ "expr ::= ID", - /* 172 */ "expr ::= JOIN_KW", - /* 173 */ "expr ::= nm DOT nm", - /* 174 */ "expr ::= nm DOT nm DOT nm", - /* 175 */ "expr ::= INTEGER", - /* 176 */ "expr ::= FLOAT", - /* 177 */ "expr ::= STRING", - /* 178 */ "expr ::= BLOB", - /* 179 */ "expr ::= VARIABLE", - /* 180 */ "expr ::= ID LP exprlist RP", - /* 181 */ "expr ::= ID LP STAR RP", - /* 182 */ "expr ::= expr AND expr", - /* 183 */ "expr ::= expr OR expr", - /* 184 */ "expr ::= expr LT expr", - /* 185 */ "expr ::= expr GT expr", - /* 186 */ "expr ::= expr LE expr", - /* 187 */ "expr ::= expr GE expr", - /* 188 */ "expr ::= expr NE expr", - /* 189 */ "expr ::= expr EQ expr", - /* 190 */ "expr ::= expr BITAND expr", - /* 191 */ "expr ::= expr BITOR expr", - /* 192 */ "expr ::= expr LSHIFT expr", - /* 193 */ "expr ::= expr RSHIFT expr", - /* 194 */ "expr ::= expr PLUS expr", - /* 195 */ "expr ::= expr MINUS expr", - /* 196 */ "expr ::= expr STAR expr", - /* 197 */ "expr ::= expr SLASH expr", - /* 198 */ "expr ::= expr REM expr", - /* 199 */ "expr ::= expr CONCAT expr", - /* 200 */ "likeop ::= LIKE", - /* 201 */ "likeop ::= GLOB", - /* 202 */ "likeop ::= NOT LIKE", - /* 203 */ "likeop ::= NOT GLOB", - /* 204 */ "expr ::= expr likeop expr", - /* 205 */ "expr ::= expr ISNULL", - /* 206 */ "expr ::= expr IS NULL", - /* 207 */ "expr ::= expr NOTNULL", - /* 208 */ "expr ::= expr NOT NULL", - /* 209 */ "expr ::= expr IS NOT NULL", - /* 210 */ "expr ::= NOT expr", - /* 211 */ "expr ::= BITNOT expr", - /* 212 */ "expr ::= MINUS expr", - /* 213 */ "expr ::= PLUS expr", - /* 214 */ "expr ::= LP select RP", - /* 215 */ "between_op ::= BETWEEN", - /* 216 */ "between_op ::= NOT BETWEEN", - /* 217 */ "expr ::= expr between_op expr AND expr", - /* 218 */ "in_op ::= IN", - /* 219 */ "in_op ::= NOT IN", - /* 220 */ "expr ::= expr in_op LP exprlist RP", - /* 221 */ "expr ::= expr in_op LP select RP", - /* 222 */ "expr ::= expr in_op nm dbnm", - /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 225 */ "case_exprlist ::= WHEN expr THEN expr", - /* 226 */ "case_else ::= ELSE expr", - /* 227 */ "case_else ::=", - /* 228 */ "case_operand ::= expr", - /* 229 */ "case_operand ::=", - /* 230 */ "exprlist ::= exprlist COMMA expritem", - /* 231 */ "exprlist ::= expritem", - /* 232 */ "expritem ::= expr", - /* 233 */ "expritem ::=", - /* 234 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON fullname LP idxlist RP onconf", - /* 235 */ "uniqueflag ::= UNIQUE", - /* 236 */ "uniqueflag ::=", - /* 237 */ "idxlist_opt ::=", - /* 238 */ "idxlist_opt ::= LP idxlist RP", - /* 239 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", - /* 240 */ "idxlist ::= idxitem collate sortorder", - /* 241 */ "idxitem ::= nm", - /* 242 */ "cmd ::= DROP INDEX fullname", - /* 243 */ "cmd ::= VACUUM", - /* 244 */ "cmd ::= VACUUM nm", - /* 245 */ "cmd ::= PRAGMA nm dbnm EQ nm", - /* 246 */ "cmd ::= PRAGMA nm dbnm EQ ON", - /* 247 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", - /* 248 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 249 */ "cmd ::= PRAGMA nm dbnm LP nm RP", - /* 250 */ "cmd ::= PRAGMA nm dbnm", - /* 251 */ "plus_num ::= plus_opt number", - /* 252 */ "minus_num ::= MINUS number", - /* 253 */ "number ::= INTEGER", - /* 254 */ "number ::= FLOAT", - /* 255 */ "plus_opt ::= PLUS", - /* 256 */ "plus_opt ::=", - /* 257 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", - /* 258 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 259 */ "trigger_time ::= BEFORE", - /* 260 */ "trigger_time ::= AFTER", - /* 261 */ "trigger_time ::= INSTEAD OF", - /* 262 */ "trigger_time ::=", - /* 263 */ "trigger_event ::= DELETE", - /* 264 */ "trigger_event ::= INSERT", - /* 265 */ "trigger_event ::= UPDATE", - /* 266 */ "trigger_event ::= UPDATE OF inscollist", - /* 267 */ "foreach_clause ::=", - /* 268 */ "foreach_clause ::= FOR EACH ROW", - /* 269 */ "foreach_clause ::= FOR EACH STATEMENT", - /* 270 */ "when_clause ::=", - /* 271 */ "when_clause ::= WHEN expr", - /* 272 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", - /* 273 */ "trigger_cmd_list ::=", - /* 274 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 275 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 276 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 277 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 278 */ "trigger_cmd ::= select", - /* 279 */ "expr ::= RAISE LP IGNORE RP", - /* 280 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 281 */ "raisetype ::= ROLLBACK", - /* 282 */ "raisetype ::= ABORT", - /* 283 */ "raisetype ::= FAIL", - /* 284 */ "cmd ::= DROP TRIGGER fullname", - /* 285 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", - /* 286 */ "key_opt ::=", - /* 287 */ "key_opt ::= KEY ids", - /* 288 */ "key_opt ::= KEY BLOB", - /* 289 */ "database_kw_opt ::= DATABASE", - /* 290 */ "database_kw_opt ::=", - /* 291 */ "cmd ::= DETACH database_kw_opt nm", + /* 59 */ "autoinc ::=", + /* 60 */ "autoinc ::= AUTOINCR", + /* 61 */ "refargs ::=", + /* 62 */ "refargs ::= refargs refarg", + /* 63 */ "refarg ::= MATCH nm", + /* 64 */ "refarg ::= ON DELETE refact", + /* 65 */ "refarg ::= ON UPDATE refact", + /* 66 */ "refarg ::= ON INSERT refact", + /* 67 */ "refact ::= SET NULL", + /* 68 */ "refact ::= SET DEFAULT", + /* 69 */ "refact ::= CASCADE", + /* 70 */ "refact ::= RESTRICT", + /* 71 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 72 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 73 */ "init_deferred_pred_opt ::=", + /* 74 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 75 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 76 */ "conslist_opt ::=", + /* 77 */ "conslist_opt ::= COMMA conslist", + /* 78 */ "conslist ::= conslist COMMA tcons", + /* 79 */ "conslist ::= conslist tcons", + /* 80 */ "conslist ::= tcons", + /* 81 */ "tcons ::= CONSTRAINT nm", + /* 82 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", + /* 83 */ "tcons ::= UNIQUE LP idxlist RP onconf", + /* 84 */ "tcons ::= CHECK expr onconf", + /* 85 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", + /* 86 */ "defer_subclause_opt ::=", + /* 87 */ "defer_subclause_opt ::= defer_subclause", + /* 88 */ "onconf ::=", + /* 89 */ "onconf ::= ON CONFLICT resolvetype", + /* 90 */ "orconf ::=", + /* 91 */ "orconf ::= OR resolvetype", + /* 92 */ "resolvetype ::= raisetype", + /* 93 */ "resolvetype ::= IGNORE", + /* 94 */ "resolvetype ::= REPLACE", + /* 95 */ "cmd ::= DROP TABLE fullname", + /* 96 */ "cmd ::= CREATE temp VIEW nm dbnm AS select", + /* 97 */ "cmd ::= DROP VIEW fullname", + /* 98 */ "cmd ::= select", + /* 99 */ "select ::= oneselect", + /* 100 */ "select ::= select multiselect_op oneselect", + /* 101 */ "multiselect_op ::= UNION", + /* 102 */ "multiselect_op ::= UNION ALL", + /* 103 */ "multiselect_op ::= INTERSECT", + /* 104 */ "multiselect_op ::= EXCEPT", + /* 105 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 106 */ "distinct ::= DISTINCT", + /* 107 */ "distinct ::= ALL", + /* 108 */ "distinct ::=", + /* 109 */ "sclp ::= selcollist COMMA", + /* 110 */ "sclp ::=", + /* 111 */ "selcollist ::= sclp expr as", + /* 112 */ "selcollist ::= sclp STAR", + /* 113 */ "selcollist ::= sclp nm DOT STAR", + /* 114 */ "as ::= AS nm", + /* 115 */ "as ::= ids", + /* 116 */ "as ::=", + /* 117 */ "from ::=", + /* 118 */ "from ::= FROM seltablist", + /* 119 */ "stl_prefix ::= seltablist joinop", + /* 120 */ "stl_prefix ::=", + /* 121 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt", + /* 122 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt", + /* 123 */ "seltablist_paren ::= select", + /* 124 */ "seltablist_paren ::= seltablist", + /* 125 */ "dbnm ::=", + /* 126 */ "dbnm ::= DOT nm", + /* 127 */ "fullname ::= nm dbnm", + /* 128 */ "joinop ::= COMMA", + /* 129 */ "joinop ::= JOIN", + /* 130 */ "joinop ::= JOIN_KW JOIN", + /* 131 */ "joinop ::= JOIN_KW nm JOIN", + /* 132 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 133 */ "on_opt ::= ON expr", + /* 134 */ "on_opt ::=", + /* 135 */ "using_opt ::= USING LP inscollist RP", + /* 136 */ "using_opt ::=", + /* 137 */ "orderby_opt ::=", + /* 138 */ "orderby_opt ::= ORDER BY sortlist", + /* 139 */ "sortlist ::= sortlist COMMA sortitem collate sortorder", + /* 140 */ "sortlist ::= sortitem collate sortorder", + /* 141 */ "sortitem ::= expr", + /* 142 */ "sortorder ::= ASC", + /* 143 */ "sortorder ::= DESC", + /* 144 */ "sortorder ::=", + /* 145 */ "collate ::=", + /* 146 */ "collate ::= COLLATE id", + /* 147 */ "groupby_opt ::=", + /* 148 */ "groupby_opt ::= GROUP BY exprlist", + /* 149 */ "having_opt ::=", + /* 150 */ "having_opt ::= HAVING expr", + /* 151 */ "limit_opt ::=", + /* 152 */ "limit_opt ::= LIMIT expr", + /* 153 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 154 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 155 */ "cmd ::= DELETE FROM fullname where_opt", + /* 156 */ "where_opt ::=", + /* 157 */ "where_opt ::= WHERE expr", + /* 158 */ "cmd ::= UPDATE orconf fullname SET setlist where_opt", + /* 159 */ "setlist ::= setlist COMMA nm EQ expr", + /* 160 */ "setlist ::= nm EQ expr", + /* 161 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP", + /* 162 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", + /* 163 */ "insert_cmd ::= INSERT orconf", + /* 164 */ "insert_cmd ::= REPLACE", + /* 165 */ "itemlist ::= itemlist COMMA expr", + /* 166 */ "itemlist ::= expr", + /* 167 */ "inscollist_opt ::=", + /* 168 */ "inscollist_opt ::= LP inscollist RP", + /* 169 */ "inscollist ::= inscollist COMMA nm", + /* 170 */ "inscollist ::= nm", + /* 171 */ "expr ::= term", + /* 172 */ "expr ::= LP expr RP", + /* 173 */ "term ::= NULL", + /* 174 */ "expr ::= ID", + /* 175 */ "expr ::= JOIN_KW", + /* 176 */ "expr ::= nm DOT nm", + /* 177 */ "expr ::= nm DOT nm DOT nm", + /* 178 */ "term ::= INTEGER", + /* 179 */ "term ::= FLOAT", + /* 180 */ "term ::= STRING", + /* 181 */ "term ::= BLOB", + /* 182 */ "expr ::= REGISTER", + /* 183 */ "expr ::= VARIABLE", + /* 184 */ "expr ::= ID LP exprlist RP", + /* 185 */ "expr ::= ID LP STAR RP", + /* 186 */ "term ::= CTIME", + /* 187 */ "term ::= CDATE", + /* 188 */ "term ::= CTIMESTAMP", + /* 189 */ "expr ::= expr AND expr", + /* 190 */ "expr ::= expr OR expr", + /* 191 */ "expr ::= expr LT expr", + /* 192 */ "expr ::= expr GT expr", + /* 193 */ "expr ::= expr LE expr", + /* 194 */ "expr ::= expr GE expr", + /* 195 */ "expr ::= expr NE expr", + /* 196 */ "expr ::= expr EQ expr", + /* 197 */ "expr ::= expr BITAND expr", + /* 198 */ "expr ::= expr BITOR expr", + /* 199 */ "expr ::= expr LSHIFT expr", + /* 200 */ "expr ::= expr RSHIFT expr", + /* 201 */ "expr ::= expr PLUS expr", + /* 202 */ "expr ::= expr MINUS expr", + /* 203 */ "expr ::= expr STAR expr", + /* 204 */ "expr ::= expr SLASH expr", + /* 205 */ "expr ::= expr REM expr", + /* 206 */ "expr ::= expr CONCAT expr", + /* 207 */ "likeop ::= LIKE", + /* 208 */ "likeop ::= GLOB", + /* 209 */ "likeop ::= NOT LIKE", + /* 210 */ "likeop ::= NOT GLOB", + /* 211 */ "escape ::= ESCAPE expr", + /* 212 */ "escape ::=", + /* 213 */ "expr ::= expr likeop expr escape", + /* 214 */ "expr ::= expr ISNULL", + /* 215 */ "expr ::= expr IS NULL", + /* 216 */ "expr ::= expr NOTNULL", + /* 217 */ "expr ::= expr NOT NULL", + /* 218 */ "expr ::= expr IS NOT NULL", + /* 219 */ "expr ::= NOT expr", + /* 220 */ "expr ::= BITNOT expr", + /* 221 */ "expr ::= MINUS expr", + /* 222 */ "expr ::= PLUS expr", + /* 223 */ "between_op ::= BETWEEN", + /* 224 */ "between_op ::= NOT BETWEEN", + /* 225 */ "expr ::= expr between_op expr AND expr", + /* 226 */ "in_op ::= IN", + /* 227 */ "in_op ::= NOT IN", + /* 228 */ "expr ::= expr in_op LP exprlist RP", + /* 229 */ "expr ::= LP select RP", + /* 230 */ "expr ::= expr in_op LP select RP", + /* 231 */ "expr ::= expr in_op nm dbnm", + /* 232 */ "expr ::= EXISTS LP select RP", + /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 235 */ "case_exprlist ::= WHEN expr THEN expr", + /* 236 */ "case_else ::= ELSE expr", + /* 237 */ "case_else ::=", + /* 238 */ "case_operand ::= expr", + /* 239 */ "case_operand ::=", + /* 240 */ "exprlist ::= exprlist COMMA expritem", + /* 241 */ "exprlist ::= expritem", + /* 242 */ "expritem ::= expr", + /* 243 */ "expritem ::=", + /* 244 */ "cmd ::= CREATE uniqueflag INDEX nm dbnm ON nm LP idxlist RP onconf", + /* 245 */ "uniqueflag ::= UNIQUE", + /* 246 */ "uniqueflag ::=", + /* 247 */ "idxlist_opt ::=", + /* 248 */ "idxlist_opt ::= LP idxlist RP", + /* 249 */ "idxlist ::= idxlist COMMA idxitem collate sortorder", + /* 250 */ "idxlist ::= idxitem collate sortorder", + /* 251 */ "idxitem ::= nm", + /* 252 */ "cmd ::= DROP INDEX fullname", + /* 253 */ "cmd ::= VACUUM", + /* 254 */ "cmd ::= VACUUM nm", + /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nm", + /* 256 */ "cmd ::= PRAGMA nm dbnm EQ ON", + /* 257 */ "cmd ::= PRAGMA nm dbnm EQ plus_num", + /* 258 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 259 */ "cmd ::= PRAGMA nm dbnm LP nm RP", + /* 260 */ "cmd ::= PRAGMA nm dbnm", + /* 261 */ "plus_num ::= plus_opt number", + /* 262 */ "minus_num ::= MINUS number", + /* 263 */ "number ::= INTEGER", + /* 264 */ "number ::= FLOAT", + /* 265 */ "plus_opt ::= PLUS", + /* 266 */ "plus_opt ::=", + /* 267 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END", + /* 268 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 269 */ "trigger_time ::= BEFORE", + /* 270 */ "trigger_time ::= AFTER", + /* 271 */ "trigger_time ::= INSTEAD OF", + /* 272 */ "trigger_time ::=", + /* 273 */ "trigger_event ::= DELETE", + /* 274 */ "trigger_event ::= INSERT", + /* 275 */ "trigger_event ::= UPDATE", + /* 276 */ "trigger_event ::= UPDATE OF inscollist", + /* 277 */ "foreach_clause ::=", + /* 278 */ "foreach_clause ::= FOR EACH ROW", + /* 279 */ "foreach_clause ::= FOR EACH STATEMENT", + /* 280 */ "when_clause ::=", + /* 281 */ "when_clause ::= WHEN expr", + /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list", + /* 283 */ "trigger_cmd_list ::=", + /* 284 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", + /* 285 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", + /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", + /* 287 */ "trigger_cmd ::= DELETE FROM nm where_opt", + /* 288 */ "trigger_cmd ::= select", + /* 289 */ "expr ::= RAISE LP IGNORE RP", + /* 290 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 291 */ "raisetype ::= ROLLBACK", + /* 292 */ "raisetype ::= ABORT", + /* 293 */ "raisetype ::= FAIL", + /* 294 */ "cmd ::= DROP TRIGGER fullname", + /* 295 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt", + /* 296 */ "key_opt ::=", + /* 297 */ "key_opt ::= KEY ids", + /* 298 */ "key_opt ::= KEY BLOB", + /* 299 */ "database_kw_opt ::= DATABASE", + /* 300 */ "database_kw_opt ::=", + /* 301 */ "cmd ::= DETACH database_kw_opt nm", + /* 302 */ "cmd ::= REINDEX", + /* 303 */ "cmd ::= REINDEX nm dbnm", + /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 306 */ "add_column_fullname ::= fullname", + /* 307 */ "kwcolumn_opt ::=", + /* 308 */ "kwcolumn_opt ::= COLUMNKW", }; #endif /* NDEBUG */ @@ -1228,63 +1312,72 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ ** which appear on the RHS of the rule, but which are not used ** inside the C code. */ - case 146: - case 176: - case 193: -#line 303 "parse.y" -{sqlite3SelectDelete((yypminor->yy107));} -#line 1238 "parse.c" - break; - case 161: - case 181: - case 183: + case 159: case 191: - case 197: - case 210: -#line 552 "parse.y" -{sqlite3ExprDelete((yypminor->yy258));} -#line 1248 "parse.c" - break; - case 162: - case 170: - case 179: - case 182: - case 184: - case 186: - case 196: - case 199: - case 200: - case 203: case 208: -#line 744 "parse.y" -{sqlite3ExprListDelete((yypminor->yy210));} -#line 1263 "parse.c" +#line 332 "parse.y" +{sqlite3SelectDelete((yypminor->yy91));} +#line 1322 "parse.c" break; - case 175: - case 180: - case 188: - case 189: -#line 428 "parse.y" -{sqlite3SrcListDelete((yypminor->yy259));} -#line 1271 "parse.c" - break; - case 192: - case 195: - case 202: -#line 446 "parse.y" -{sqlite3IdListDelete((yypminor->yy272));} -#line 1278 "parse.c" - break; - case 216: - case 221: -#line 833 "parse.y" -{sqlite3DeleteTriggerStep((yypminor->yy91));} -#line 1284 "parse.c" + case 172: + case 176: + case 196: + case 198: + case 206: + case 212: + case 226: +#line 591 "parse.y" +{sqlite3ExprDelete((yypminor->yy418));} +#line 1333 "parse.c" break; + case 177: + case 185: + case 194: + case 197: + case 199: + case 201: + case 211: + case 214: + case 215: case 218: -#line 817 "parse.y" -{sqlite3IdListDelete((yypminor->yy146).b);} -#line 1289 "parse.c" + case 224: +#line 810 "parse.y" +{sqlite3ExprListDelete((yypminor->yy322));} +#line 1348 "parse.c" + break; + case 190: + case 195: + case 203: + case 204: +#line 461 "parse.y" +{sqlite3SrcListDelete((yypminor->yy439));} +#line 1356 "parse.c" + break; + case 200: +#line 523 "parse.y" +{ + sqlite3ExprDelete((yypminor->yy388).pLimit); + sqlite3ExprDelete((yypminor->yy388).pOffset); +} +#line 1364 "parse.c" + break; + case 207: + case 210: + case 217: +#line 479 "parse.y" +{sqlite3IdListDelete((yypminor->yy232));} +#line 1371 "parse.c" + break; + case 232: + case 237: +#line 903 "parse.y" +{sqlite3DeleteTriggerStep((yypminor->yy451));} +#line 1377 "parse.c" + break; + case 234: +#line 887 "parse.y" +{sqlite3IdListDelete((yypminor->yy378).b);} +#line 1382 "parse.c" break; default: break; /* If no destructor action specified: do nothing */ } @@ -1391,11 +1484,11 @@ static int yy_find_shift_action( ** return YY_NO_ACTION. */ static int yy_find_reduce_action( - yyParser *pParser, /* The parser */ + int stateno, /* Current state number */ int iLookAhead /* The look-ahead token */ ){ int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; + /* int stateno = pParser->yystack[pParser->yyidx].stateno; */ i = yy_reduce_ofst[stateno]; if( i==YY_REDUCE_USE_DFLT ){ @@ -1460,298 +1553,315 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ unsigned char nrhs; /* Number of right-hand side symbols in the rule */ } yyRuleInfo[] = { - { 131, 1 }, - { 132, 2 }, - { 132, 1 }, - { 133, 3 }, - { 133, 1 }, - { 135, 1 }, - { 134, 1 }, - { 134, 0 }, - { 136, 3 }, - { 138, 0 }, - { 138, 1 }, - { 138, 2 }, - { 137, 0 }, - { 137, 1 }, - { 137, 1 }, - { 137, 1 }, - { 136, 2 }, - { 136, 2 }, - { 136, 2 }, - { 136, 2 }, - { 140, 5 }, - { 142, 1 }, - { 142, 0 }, - { 141, 4 }, - { 141, 2 }, - { 144, 3 }, { 144, 1 }, - { 147, 3 }, - { 148, 1 }, - { 151, 1 }, - { 152, 1 }, - { 152, 1 }, - { 139, 1 }, - { 139, 1 }, - { 139, 1 }, - { 149, 0 }, - { 149, 1 }, - { 149, 4 }, - { 149, 6 }, - { 153, 1 }, - { 153, 2 }, - { 154, 1 }, - { 154, 1 }, - { 150, 2 }, - { 150, 0 }, - { 157, 3 }, - { 157, 1 }, - { 157, 2 }, - { 157, 2 }, - { 157, 2 }, - { 157, 2 }, - { 158, 2 }, - { 158, 3 }, - { 158, 4 }, - { 158, 2 }, - { 158, 5 }, - { 158, 4 }, - { 158, 1 }, - { 158, 2 }, - { 163, 0 }, - { 163, 2 }, - { 165, 2 }, - { 165, 3 }, - { 165, 3 }, - { 165, 3 }, - { 166, 2 }, - { 166, 2 }, - { 166, 1 }, - { 166, 1 }, - { 164, 3 }, - { 164, 2 }, - { 167, 0 }, - { 167, 2 }, - { 167, 2 }, - { 145, 0 }, { 145, 2 }, - { 168, 3 }, - { 168, 2 }, - { 168, 1 }, - { 169, 2 }, - { 169, 6 }, - { 169, 5 }, - { 169, 3 }, - { 169, 10 }, - { 171, 0 }, - { 171, 1 }, - { 159, 0 }, - { 159, 3 }, - { 172, 0 }, - { 172, 2 }, - { 173, 1 }, - { 173, 1 }, - { 173, 1 }, - { 136, 3 }, - { 136, 7 }, - { 136, 3 }, - { 136, 1 }, + { 145, 1 }, + { 147, 1 }, { 146, 1 }, { 146, 3 }, - { 177, 1 }, - { 177, 2 }, - { 177, 1 }, - { 177, 1 }, - { 176, 9 }, - { 178, 1 }, - { 178, 1 }, + { 149, 0 }, + { 149, 1 }, + { 148, 3 }, + { 151, 0 }, + { 151, 1 }, + { 151, 2 }, + { 150, 0 }, + { 150, 1 }, + { 150, 1 }, + { 150, 1 }, + { 148, 2 }, + { 148, 2 }, + { 148, 2 }, + { 148, 2 }, + { 153, 5 }, + { 155, 1 }, + { 155, 0 }, + { 154, 4 }, + { 154, 2 }, + { 157, 3 }, + { 157, 1 }, + { 160, 3 }, + { 161, 1 }, + { 164, 1 }, + { 165, 1 }, + { 165, 1 }, + { 152, 1 }, + { 152, 1 }, + { 152, 1 }, + { 162, 0 }, + { 162, 1 }, + { 162, 4 }, + { 162, 6 }, + { 166, 1 }, + { 166, 2 }, + { 167, 1 }, + { 167, 1 }, + { 163, 2 }, + { 163, 0 }, + { 170, 3 }, + { 170, 1 }, + { 170, 2 }, + { 170, 3 }, + { 170, 3 }, + { 170, 2 }, + { 171, 2 }, + { 171, 3 }, + { 171, 5 }, + { 171, 2 }, + { 171, 5 }, + { 171, 4 }, + { 171, 1 }, + { 171, 2 }, + { 175, 0 }, + { 175, 1 }, { 178, 0 }, - { 186, 2 }, - { 186, 0 }, + { 178, 2 }, + { 180, 2 }, + { 180, 3 }, + { 180, 3 }, + { 180, 3 }, + { 181, 2 }, + { 181, 2 }, + { 181, 1 }, + { 181, 1 }, { 179, 3 }, { 179, 2 }, - { 179, 4 }, - { 187, 2 }, - { 187, 1 }, - { 187, 0 }, - { 180, 0 }, - { 180, 2 }, - { 189, 2 }, - { 189, 0 }, - { 188, 6 }, - { 188, 7 }, - { 193, 1 }, - { 193, 1 }, - { 143, 0 }, - { 143, 2 }, - { 175, 2 }, - { 190, 1 }, - { 190, 1 }, - { 190, 2 }, - { 190, 3 }, - { 190, 4 }, - { 191, 2 }, - { 191, 0 }, - { 192, 4 }, - { 192, 0 }, - { 184, 0 }, - { 184, 3 }, - { 196, 5 }, - { 196, 3 }, - { 197, 1 }, - { 160, 1 }, - { 160, 1 }, - { 160, 0 }, - { 198, 0 }, - { 198, 2 }, { 182, 0 }, - { 182, 3 }, - { 183, 0 }, + { 182, 2 }, + { 182, 2 }, + { 158, 0 }, + { 158, 2 }, + { 183, 3 }, { 183, 2 }, - { 185, 0 }, - { 185, 2 }, - { 185, 4 }, - { 185, 4 }, - { 136, 4 }, - { 181, 0 }, - { 181, 2 }, - { 136, 6 }, - { 200, 5 }, - { 200, 3 }, - { 136, 8 }, - { 136, 5 }, + { 183, 1 }, + { 184, 2 }, + { 184, 7 }, + { 184, 5 }, + { 184, 3 }, + { 184, 10 }, + { 186, 0 }, + { 186, 1 }, + { 173, 0 }, + { 173, 3 }, + { 187, 0 }, + { 187, 2 }, + { 188, 1 }, + { 188, 1 }, + { 188, 1 }, + { 148, 3 }, + { 148, 7 }, + { 148, 3 }, + { 148, 1 }, + { 159, 1 }, + { 159, 3 }, + { 192, 1 }, + { 192, 2 }, + { 192, 1 }, + { 192, 1 }, + { 191, 9 }, + { 193, 1 }, + { 193, 1 }, + { 193, 0 }, { 201, 2 }, - { 201, 1 }, - { 203, 3 }, - { 203, 1 }, + { 201, 0 }, + { 194, 3 }, + { 194, 2 }, + { 194, 4 }, + { 202, 2 }, + { 202, 1 }, { 202, 0 }, - { 202, 3 }, - { 195, 3 }, - { 195, 1 }, - { 161, 3 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 3 }, - { 161, 5 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 1 }, - { 161, 4 }, - { 161, 4 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 161, 3 }, - { 204, 1 }, - { 204, 1 }, + { 195, 0 }, + { 195, 2 }, { 204, 2 }, - { 204, 2 }, - { 161, 3 }, - { 161, 2 }, - { 161, 3 }, - { 161, 2 }, - { 161, 3 }, - { 161, 4 }, - { 161, 2 }, - { 161, 2 }, - { 161, 2 }, - { 161, 2 }, - { 161, 3 }, + { 204, 0 }, + { 203, 6 }, + { 203, 7 }, + { 208, 1 }, + { 208, 1 }, + { 156, 0 }, + { 156, 2 }, + { 190, 2 }, + { 205, 1 }, { 205, 1 }, { 205, 2 }, - { 161, 5 }, - { 206, 1 }, + { 205, 3 }, + { 205, 4 }, { 206, 2 }, - { 161, 5 }, - { 161, 5 }, - { 161, 4 }, - { 161, 5 }, - { 208, 5 }, - { 208, 4 }, - { 209, 2 }, - { 209, 0 }, - { 207, 1 }, + { 206, 0 }, + { 207, 4 }, { 207, 0 }, + { 199, 0 }, { 199, 3 }, - { 199, 1 }, - { 210, 1 }, - { 210, 0 }, - { 136, 11 }, - { 211, 1 }, - { 211, 0 }, - { 162, 0 }, - { 162, 3 }, - { 170, 5 }, - { 170, 3 }, + { 211, 5 }, + { 211, 3 }, { 212, 1 }, - { 136, 3 }, - { 136, 1 }, - { 136, 2 }, - { 136, 5 }, - { 136, 5 }, - { 136, 5 }, - { 136, 5 }, - { 136, 6 }, - { 136, 3 }, - { 155, 2 }, - { 156, 2 }, - { 214, 1 }, - { 214, 1 }, - { 213, 1 }, + { 174, 1 }, + { 174, 1 }, + { 174, 0 }, { 213, 0 }, - { 136, 5 }, - { 215, 10 }, - { 217, 1 }, - { 217, 1 }, - { 217, 2 }, - { 217, 0 }, - { 218, 1 }, - { 218, 1 }, - { 218, 1 }, + { 213, 2 }, + { 197, 0 }, + { 197, 3 }, + { 198, 0 }, + { 198, 2 }, + { 200, 0 }, + { 200, 2 }, + { 200, 4 }, + { 200, 4 }, + { 148, 4 }, + { 196, 0 }, + { 196, 2 }, + { 148, 6 }, + { 215, 5 }, + { 215, 3 }, + { 148, 8 }, + { 148, 5 }, + { 216, 2 }, + { 216, 1 }, { 218, 3 }, - { 219, 0 }, - { 219, 3 }, - { 219, 3 }, - { 220, 0 }, + { 218, 1 }, + { 217, 0 }, + { 217, 3 }, + { 210, 3 }, + { 210, 1 }, + { 176, 1 }, + { 176, 3 }, + { 172, 1 }, + { 176, 1 }, + { 176, 1 }, + { 176, 3 }, + { 176, 5 }, + { 172, 1 }, + { 172, 1 }, + { 172, 1 }, + { 172, 1 }, + { 176, 1 }, + { 176, 1 }, + { 176, 4 }, + { 176, 4 }, + { 172, 1 }, + { 172, 1 }, + { 172, 1 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 176, 3 }, + { 219, 1 }, + { 219, 1 }, + { 219, 2 }, + { 219, 2 }, { 220, 2 }, - { 216, 3 }, - { 216, 0 }, - { 221, 6 }, - { 221, 8 }, - { 221, 5 }, - { 221, 4 }, + { 220, 0 }, + { 176, 4 }, + { 176, 2 }, + { 176, 3 }, + { 176, 2 }, + { 176, 3 }, + { 176, 4 }, + { 176, 2 }, + { 176, 2 }, + { 176, 2 }, + { 176, 2 }, { 221, 1 }, - { 161, 4 }, - { 161, 6 }, - { 174, 1 }, - { 174, 1 }, - { 174, 1 }, - { 136, 3 }, - { 136, 6 }, - { 223, 0 }, - { 223, 2 }, - { 223, 2 }, + { 221, 2 }, + { 176, 5 }, { 222, 1 }, - { 222, 0 }, - { 136, 3 }, + { 222, 2 }, + { 176, 5 }, + { 176, 3 }, + { 176, 5 }, + { 176, 4 }, + { 176, 4 }, + { 176, 5 }, + { 224, 5 }, + { 224, 4 }, + { 225, 2 }, + { 225, 0 }, + { 223, 1 }, + { 223, 0 }, + { 214, 3 }, + { 214, 1 }, + { 226, 1 }, + { 226, 0 }, + { 148, 11 }, + { 227, 1 }, + { 227, 0 }, + { 177, 0 }, + { 177, 3 }, + { 185, 5 }, + { 185, 3 }, + { 228, 1 }, + { 148, 3 }, + { 148, 1 }, + { 148, 2 }, + { 148, 5 }, + { 148, 5 }, + { 148, 5 }, + { 148, 5 }, + { 148, 6 }, + { 148, 3 }, + { 168, 2 }, + { 169, 2 }, + { 230, 1 }, + { 230, 1 }, + { 229, 1 }, + { 229, 0 }, + { 148, 5 }, + { 231, 10 }, + { 233, 1 }, + { 233, 1 }, + { 233, 2 }, + { 233, 0 }, + { 234, 1 }, + { 234, 1 }, + { 234, 1 }, + { 234, 3 }, + { 235, 0 }, + { 235, 3 }, + { 235, 3 }, + { 236, 0 }, + { 236, 2 }, + { 232, 3 }, + { 232, 0 }, + { 237, 6 }, + { 237, 8 }, + { 237, 5 }, + { 237, 4 }, + { 237, 1 }, + { 176, 4 }, + { 176, 6 }, + { 189, 1 }, + { 189, 1 }, + { 189, 1 }, + { 148, 3 }, + { 148, 6 }, + { 239, 0 }, + { 239, 2 }, + { 239, 2 }, + { 238, 1 }, + { 238, 0 }, + { 148, 3 }, + { 148, 1 }, + { 148, 3 }, + { 148, 6 }, + { 148, 6 }, + { 240, 1 }, + { 241, 0 }, + { 241, 1 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -1779,6 +1889,18 @@ static void yy_reduce( } #endif /* NDEBUG */ +#ifndef NDEBUG + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + */ + memset(&yygotominor, 0, sizeof(yygotominor)); +#endif + switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example ** follows: @@ -1788,99 +1910,112 @@ static void yy_reduce( ** #line ** break; */ - case 5: -#line 86 "parse.y" + case 3: +#line 84 "parse.y" { sqlite3FinishCoding(pParse); } -#line 1796 "parse.c" +#line 1918 "parse.c" break; case 6: #line 87 "parse.y" -{ sqlite3BeginParse(pParse, 1); } -#line 1801 "parse.c" +{ sqlite3BeginParse(pParse, 0); } +#line 1923 "parse.c" break; case 7: -#line 88 "parse.y" -{ sqlite3BeginParse(pParse, 0); } -#line 1806 "parse.c" +#line 89 "parse.y" +{ sqlite3BeginParse(pParse, 1); } +#line 1928 "parse.c" break; case 8: -#line 93 "parse.y" -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy284);} -#line 1811 "parse.c" +#line 95 "parse.y" +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);} +#line 1933 "parse.c" break; case 12: -#line 98 "parse.y" -{yygotominor.yy284 = TK_DEFERRED;} -#line 1816 "parse.c" +#line 100 "parse.y" +{yygotominor.yy328 = TK_DEFERRED;} +#line 1938 "parse.c" break; case 13: case 14: case 15: - case 99: case 101: - case 102: -#line 99 "parse.y" -{yygotominor.yy284 = yymsp[0].major;} -#line 1826 "parse.c" + case 103: + case 104: +#line 101 "parse.y" +{yygotominor.yy328 = yymsp[0].major;} +#line 1948 "parse.c" break; case 16: case 17: -#line 102 "parse.y" +#line 104 "parse.y" {sqlite3CommitTransaction(pParse);} -#line 1832 "parse.c" +#line 1954 "parse.c" break; case 18: -#line 104 "parse.y" +#line 106 "parse.y" {sqlite3RollbackTransaction(pParse);} -#line 1837 "parse.c" +#line 1959 "parse.c" break; case 20: -#line 109 "parse.y" +#line 111 "parse.y" { - sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98,yymsp[-3].minor.yy284,0); + sqlite3StartTable(pParse,&yymsp[-4].minor.yy0,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430,yymsp[-3].minor.yy328,0); } -#line 1844 "parse.c" +#line 1966 "parse.c" break; case 21: - case 72: - case 104: - case 216: - case 219: -#line 113 "parse.y" -{yygotominor.yy284 = 1;} -#line 1853 "parse.c" + case 60: + case 74: + case 106: + case 224: + case 227: +#line 115 "parse.y" +{yygotominor.yy328 = 1;} +#line 1976 "parse.c" break; case 22: - case 71: + case 59: case 73: - case 84: - case 105: - case 106: - case 215: - case 218: -#line 114 "parse.y" -{yygotominor.yy284 = 0;} -#line 1865 "parse.c" + case 75: + case 86: + case 107: + case 108: + case 223: + case 226: +#line 116 "parse.y" +{yygotominor.yy328 = 0;} +#line 1989 "parse.c" break; case 23: -#line 115 "parse.y" +#line 117 "parse.y" { - sqlite3EndTable(pParse,&yymsp[0].minor.yy0,0); + sqlite3EndTable(pParse,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy0,0); } -#line 1872 "parse.c" +#line 1996 "parse.c" break; case 24: -#line 118 "parse.y" +#line 120 "parse.y" { - sqlite3EndTable(pParse,0,yymsp[0].minor.yy107); - sqlite3SelectDelete(yymsp[0].minor.yy107); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy91); + sqlite3SelectDelete(yymsp[0].minor.yy91); } -#line 1880 "parse.c" +#line 2004 "parse.c" + break; + case 27: +#line 131 "parse.y" +{ + yygotominor.yy430.z = yymsp[-2].minor.yy430.z; + yygotominor.yy430.n = (pParse->sLastToken.z-yymsp[-2].minor.yy430.z) + pParse->sLastToken.n; +} +#line 2012 "parse.c" break; case 28: -#line 130 "parse.y" -{sqlite3AddColumn(pParse,&yymsp[0].minor.yy98);} -#line 1885 "parse.c" +#line 135 "parse.y" +{ + sqlite3AddColumn(pParse,&yymsp[0].minor.yy430); + yygotominor.yy430 = yymsp[0].minor.yy430; +} +#line 2020 "parse.c" break; case 29: case 30: @@ -1888,600 +2023,634 @@ static void yy_reduce( case 32: case 33: case 34: - case 253: - case 254: -#line 136 "parse.y" -{yygotominor.yy98 = yymsp[0].minor.yy0;} -#line 1897 "parse.c" + case 263: + case 264: +#line 145 "parse.y" +{yygotominor.yy430 = yymsp[0].minor.yy0;} +#line 2032 "parse.c" break; case 36: -#line 185 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy98,&yymsp[0].minor.yy98);} -#line 1902 "parse.c" +#line 200 "parse.y" +{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy430,&yymsp[0].minor.yy430);} +#line 2037 "parse.c" break; case 37: -#line 186 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy98,&yymsp[0].minor.yy0);} -#line 1907 "parse.c" +#line 201 "parse.y" +{sqlite3AddColumnType(pParse,&yymsp[-3].minor.yy430,&yymsp[0].minor.yy0);} +#line 2042 "parse.c" break; case 38: -#line 188 "parse.y" -{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy98,&yymsp[0].minor.yy0);} -#line 1912 "parse.c" +#line 203 "parse.y" +{sqlite3AddColumnType(pParse,&yymsp[-5].minor.yy430,&yymsp[0].minor.yy0);} +#line 2047 "parse.c" break; case 39: - case 112: - case 113: - case 124: - case 144: - case 241: + case 114: + case 115: + case 126: + case 146: case 251: - case 252: -#line 190 "parse.y" -{yygotominor.yy98 = yymsp[0].minor.yy98;} -#line 1924 "parse.c" + case 261: + case 262: +#line 205 "parse.y" +{yygotominor.yy430 = yymsp[0].minor.yy430;} +#line 2059 "parse.c" break; case 40: -#line 191 "parse.y" -{yygotominor.yy98.z=yymsp[-1].minor.yy98.z; yygotominor.yy98.n=yymsp[0].minor.yy98.n+(yymsp[0].minor.yy98.z-yymsp[-1].minor.yy98.z);} -#line 1929 "parse.c" +#line 206 "parse.y" +{yygotominor.yy430.z=yymsp[-1].minor.yy430.z; yygotominor.yy430.n=yymsp[0].minor.yy430.n+(yymsp[0].minor.yy430.z-yymsp[-1].minor.yy430.z);} +#line 2064 "parse.c" break; case 41: -#line 193 "parse.y" -{ yygotominor.yy284 = atoi(yymsp[0].minor.yy98.z); } -#line 1934 "parse.c" +#line 208 "parse.y" +{ yygotominor.yy328 = atoi(yymsp[0].minor.yy430.z); } +#line 2069 "parse.c" break; case 42: -#line 194 "parse.y" -{ yygotominor.yy284 = -atoi(yymsp[0].minor.yy98.z); } -#line 1939 "parse.c" +#line 209 "parse.y" +{ yygotominor.yy328 = -atoi(yymsp[0].minor.yy430.z); } +#line 2074 "parse.c" break; case 47: case 48: -#line 199 "parse.y" -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy98,0);} -#line 1945 "parse.c" +#line 214 "parse.y" +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy418);} +#line 2080 "parse.c" break; case 49: -#line 201 "parse.y" -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy98,1);} -#line 1950 "parse.c" +#line 216 "parse.y" +{ + Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy418, 0, 0); + sqlite3AddDefaultValue(pParse,p); +} +#line 2088 "parse.c" + break; + case 50: +#line 220 "parse.y" +{ + Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy430); + sqlite3AddDefaultValue(pParse,p); +} +#line 2096 "parse.c" break; case 52: -#line 208 "parse.y" -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy284);} -#line 1955 "parse.c" +#line 229 "parse.y" +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);} +#line 2101 "parse.c" break; case 53: -#line 209 "parse.y" -{sqlite3AddPrimaryKey(pParse,0,yymsp[0].minor.yy284);} -#line 1960 "parse.c" +#line 231 "parse.y" +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328);} +#line 2106 "parse.c" break; case 54: -#line 210 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy284,0,0);} -#line 1965 "parse.c" - break; - case 56: -#line 213 "parse.y" -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy98,yymsp[-1].minor.yy210,yymsp[0].minor.yy284);} -#line 1970 "parse.c" - break; - case 57: -#line 214 "parse.y" -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy284);} -#line 1975 "parse.c" - break; - case 58: -#line 215 "parse.y" -{sqlite3AddCollateType(pParse, yymsp[0].minor.yy98.z, yymsp[0].minor.yy98.n);} -#line 1980 "parse.c" - break; - case 59: -#line 223 "parse.y" -{ yygotominor.yy284 = OE_Restrict * 0x010101; } -#line 1985 "parse.c" - break; - case 60: -#line 224 "parse.y" -{ yygotominor.yy284 = (yymsp[-1].minor.yy284 & yymsp[0].minor.yy47.mask) | yymsp[0].minor.yy47.value; } -#line 1990 "parse.c" - break; - case 61: -#line 226 "parse.y" -{ yygotominor.yy47.value = 0; yygotominor.yy47.mask = 0x000000; } -#line 1995 "parse.c" - break; - case 62: -#line 227 "parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy284; yygotominor.yy47.mask = 0x0000ff; } -#line 2000 "parse.c" - break; - case 63: -#line 228 "parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy284<<8; yygotominor.yy47.mask = 0x00ff00; } -#line 2005 "parse.c" - break; - case 64: -#line 229 "parse.y" -{ yygotominor.yy47.value = yymsp[0].minor.yy284<<16; yygotominor.yy47.mask = 0xff0000; } -#line 2010 "parse.c" - break; - case 65: -#line 231 "parse.y" -{ yygotominor.yy284 = OE_SetNull; } -#line 2015 "parse.c" - break; - case 66: #line 232 "parse.y" -{ yygotominor.yy284 = OE_SetDflt; } -#line 2020 "parse.c" - break; - case 67: -#line 233 "parse.y" -{ yygotominor.yy284 = OE_Cascade; } -#line 2025 "parse.c" - break; - case 68: -#line 234 "parse.y" -{ yygotominor.yy284 = OE_Restrict; } -#line 2030 "parse.c" - break; - case 69: - case 70: - case 85: - case 87: - case 89: - case 90: - case 161: -#line 236 "parse.y" -{yygotominor.yy284 = yymsp[0].minor.yy284;} -#line 2041 "parse.c" - break; - case 80: -#line 253 "parse.y" -{sqlite3AddPrimaryKey(pParse,yymsp[-2].minor.yy210,yymsp[0].minor.yy284);} -#line 2046 "parse.c" - break; - case 81: -#line 255 "parse.y" -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy210,yymsp[0].minor.yy284,0,0);} -#line 2051 "parse.c" - break; - case 83: -#line 258 "parse.y" -{ - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy210, &yymsp[-3].minor.yy98, yymsp[-2].minor.yy210, yymsp[-1].minor.yy284); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy284); -} -#line 2059 "parse.c" - break; - case 86: - case 88: -#line 272 "parse.y" -{yygotominor.yy284 = OE_Default;} -#line 2065 "parse.c" - break; - case 91: -#line 277 "parse.y" -{yygotominor.yy284 = OE_Ignore;} -#line 2070 "parse.c" - break; - case 92: - case 162: -#line 278 "parse.y" -{yygotominor.yy284 = OE_Replace;} -#line 2076 "parse.c" - break; - case 93: -#line 282 "parse.y" -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0); -} -#line 2083 "parse.c" - break; - case 94: -#line 288 "parse.y" -{ - sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy98, &yymsp[-2].minor.yy98, yymsp[0].minor.yy107, yymsp[-5].minor.yy284); -} -#line 2090 "parse.c" - break; - case 95: -#line 291 "parse.y" -{ - sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1); -} -#line 2097 "parse.c" - break; - case 96: -#line 297 "parse.y" -{ - sqlite3Select(pParse, yymsp[0].minor.yy107, SRT_Callback, 0, 0, 0, 0, 0); - sqlite3SelectDelete(yymsp[0].minor.yy107); -} -#line 2105 "parse.c" - break; - case 97: - case 121: -#line 307 "parse.y" -{yygotominor.yy107 = yymsp[0].minor.yy107;} +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0);} #line 2111 "parse.c" break; - case 98: -#line 308 "parse.y" -{ - if( yymsp[0].minor.yy107 ){ - yymsp[0].minor.yy107->op = yymsp[-1].minor.yy284; - yymsp[0].minor.yy107->pPrior = yymsp[-2].minor.yy107; - } - yygotominor.yy107 = yymsp[0].minor.yy107; -} -#line 2122 "parse.c" + case 55: +#line 233 "parse.y" +{sqlite3ExprDelete(yymsp[-2].minor.yy418);} +#line 2116 "parse.c" break; - case 100: -#line 317 "parse.y" -{yygotominor.yy284 = TK_ALL;} -#line 2127 "parse.c" + case 56: +#line 235 "parse.y" +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy430,yymsp[-1].minor.yy322,yymsp[0].minor.yy328);} +#line 2121 "parse.c" break; - case 103: -#line 321 "parse.y" -{ - yygotominor.yy107 = sqlite3SelectNew(yymsp[-6].minor.yy210,yymsp[-5].minor.yy259,yymsp[-4].minor.yy258,yymsp[-3].minor.yy210,yymsp[-2].minor.yy258,yymsp[-1].minor.yy210,yymsp[-7].minor.yy284,yymsp[0].minor.yy404.limit,yymsp[0].minor.yy404.offset); -} -#line 2134 "parse.c" + case 57: +#line 236 "parse.y" +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);} +#line 2126 "parse.c" break; - case 107: - case 238: -#line 342 "parse.y" -{yygotominor.yy210 = yymsp[-1].minor.yy210;} -#line 2140 "parse.c" + case 58: +#line 237 "parse.y" +{sqlite3AddCollateType(pParse, yymsp[0].minor.yy430.z, yymsp[0].minor.yy430.n);} +#line 2131 "parse.c" break; - case 108: - case 135: - case 145: - case 237: -#line 343 "parse.y" -{yygotominor.yy210 = 0;} -#line 2148 "parse.c" + case 61: +#line 250 "parse.y" +{ yygotominor.yy328 = OE_Restrict * 0x010101; } +#line 2136 "parse.c" break; - case 109: -#line 344 "parse.y" -{ - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-2].minor.yy210,yymsp[-1].minor.yy258,yymsp[0].minor.yy98.n?&yymsp[0].minor.yy98:0); -} -#line 2155 "parse.c" + case 62: +#line 251 "parse.y" +{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & yymsp[0].minor.yy319.mask) | yymsp[0].minor.yy319.value; } +#line 2141 "parse.c" break; - case 110: -#line 347 "parse.y" -{ - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-1].minor.yy210, sqlite3Expr(TK_ALL, 0, 0, 0), 0); -} -#line 2162 "parse.c" + case 63: +#line 253 "parse.y" +{ yygotominor.yy319.value = 0; yygotominor.yy319.mask = 0x000000; } +#line 2146 "parse.c" break; - case 111: -#line 350 "parse.y" -{ - Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); - Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy98); - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-3].minor.yy210, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); -} + case 64: +#line 254 "parse.y" +{ yygotominor.yy319.value = yymsp[0].minor.yy328; yygotominor.yy319.mask = 0x0000ff; } +#line 2151 "parse.c" + break; + case 65: +#line 255 "parse.y" +{ yygotominor.yy319.value = yymsp[0].minor.yy328<<8; yygotominor.yy319.mask = 0x00ff00; } +#line 2156 "parse.c" + break; + case 66: +#line 256 "parse.y" +{ yygotominor.yy319.value = yymsp[0].minor.yy328<<16; yygotominor.yy319.mask = 0xff0000; } +#line 2161 "parse.c" + break; + case 67: +#line 258 "parse.y" +{ yygotominor.yy328 = OE_SetNull; } +#line 2166 "parse.c" + break; + case 68: +#line 259 "parse.y" +{ yygotominor.yy328 = OE_SetDflt; } #line 2171 "parse.c" break; - case 114: -#line 362 "parse.y" -{yygotominor.yy98.n = 0;} + case 69: +#line 260 "parse.y" +{ yygotominor.yy328 = OE_Cascade; } #line 2176 "parse.c" break; - case 115: -#line 374 "parse.y" -{yygotominor.yy259 = sqliteMalloc(sizeof(*yygotominor.yy259));} + case 70: +#line 261 "parse.y" +{ yygotominor.yy328 = OE_Restrict; } #line 2181 "parse.c" break; - case 116: -#line 375 "parse.y" -{yygotominor.yy259 = yymsp[0].minor.yy259;} -#line 2186 "parse.c" + case 71: + case 72: + case 87: + case 89: + case 91: + case 92: + case 163: +#line 263 "parse.y" +{yygotominor.yy328 = yymsp[0].minor.yy328;} +#line 2192 "parse.c" break; - case 117: -#line 380 "parse.y" + case 76: +#line 273 "parse.y" +{yygotominor.yy430.n = 0; yygotominor.yy430.z = 0;} +#line 2197 "parse.c" + break; + case 77: +#line 274 "parse.y" +{yygotominor.yy430 = yymsp[-1].minor.yy0;} +#line 2202 "parse.c" + break; + case 82: +#line 280 "parse.y" +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);} +#line 2207 "parse.c" + break; + case 83: +#line 282 "parse.y" +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy328,0,0);} +#line 2212 "parse.c" + break; + case 85: +#line 285 "parse.y" { - yygotominor.yy259 = yymsp[-1].minor.yy259; - if( yygotominor.yy259 && yygotominor.yy259->nSrc>0 ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = yymsp[0].minor.yy284; + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy430, yymsp[-2].minor.yy322, yymsp[-1].minor.yy328); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328); } -#line 2194 "parse.c" +#line 2220 "parse.c" break; - case 118: -#line 384 "parse.y" -{yygotominor.yy259 = 0;} -#line 2199 "parse.c" + case 88: + case 90: +#line 299 "parse.y" +{yygotominor.yy328 = OE_Default;} +#line 2226 "parse.c" break; - case 119: -#line 385 "parse.y" + case 93: +#line 304 "parse.y" +{yygotominor.yy328 = OE_Ignore;} +#line 2231 "parse.c" + break; + case 94: + case 164: +#line 305 "parse.y" +{yygotominor.yy328 = OE_Replace;} +#line 2237 "parse.c" + break; + case 95: +#line 309 "parse.y" { - yygotominor.yy259 = sqlite3SrcListAppend(yymsp[-5].minor.yy259,&yymsp[-4].minor.yy98,&yymsp[-3].minor.yy98); - if( yymsp[-2].minor.yy98.n ) sqlite3SrcListAddAlias(yygotominor.yy259,&yymsp[-2].minor.yy98); - if( yymsp[-1].minor.yy258 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pOn = yymsp[-1].minor.yy258; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy258); } - } - if( yymsp[0].minor.yy272 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pUsing = yymsp[0].minor.yy272; } - else { sqlite3IdListDelete(yymsp[0].minor.yy272); } - } + sqlite3DropTable(pParse, yymsp[0].minor.yy439, 0); } -#line 2215 "parse.c" - break; - case 120: -#line 398 "parse.y" -{ - yygotominor.yy259 = sqlite3SrcListAppend(yymsp[-6].minor.yy259,0,0); - yygotominor.yy259->a[yygotominor.yy259->nSrc-1].pSelect = yymsp[-4].minor.yy107; - if( yymsp[-2].minor.yy98.n ) sqlite3SrcListAddAlias(yygotominor.yy259,&yymsp[-2].minor.yy98); - if( yymsp[-1].minor.yy258 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pOn = yymsp[-1].minor.yy258; } - else { sqlite3ExprDelete(yymsp[-1].minor.yy258); } - } - if( yymsp[0].minor.yy272 ){ - if( yygotominor.yy259 && yygotominor.yy259->nSrc>1 ){ yygotominor.yy259->a[yygotominor.yy259->nSrc-2].pUsing = yymsp[0].minor.yy272; } - else { sqlite3IdListDelete(yymsp[0].minor.yy272); } - } -} -#line 2232 "parse.c" - break; - case 122: -#line 419 "parse.y" -{ - yygotominor.yy107 = sqlite3SelectNew(0,yymsp[0].minor.yy259,0,0,0,0,0,-1,0); -} -#line 2239 "parse.c" - break; - case 123: -#line 424 "parse.y" -{yygotominor.yy98.z=0; yygotominor.yy98.n=0;} #line 2244 "parse.c" break; - case 125: -#line 429 "parse.y" -{yygotominor.yy259 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98);} -#line 2249 "parse.c" + case 96: +#line 316 "parse.y" +{ + sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy430, &yymsp[-2].minor.yy430, yymsp[0].minor.yy91, yymsp[-5].minor.yy328); +} +#line 2251 "parse.c" break; - case 126: - case 127: -#line 433 "parse.y" -{ yygotominor.yy284 = JT_INNER; } -#line 2255 "parse.c" + case 97: +#line 319 "parse.y" +{ + sqlite3DropTable(pParse, yymsp[0].minor.yy439, 1); +} +#line 2258 "parse.c" break; - case 128: -#line 435 "parse.y" -{ yygotominor.yy284 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } -#line 2260 "parse.c" + case 98: +#line 326 "parse.y" +{ + sqlite3Select(pParse, yymsp[0].minor.yy91, SRT_Callback, 0, 0, 0, 0, 0); + sqlite3SelectDelete(yymsp[0].minor.yy91); +} +#line 2266 "parse.c" break; - case 129: -#line 436 "parse.y" -{ yygotominor.yy284 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy98,0); } -#line 2265 "parse.c" + case 99: + case 123: +#line 336 "parse.y" +{yygotominor.yy91 = yymsp[0].minor.yy91;} +#line 2272 "parse.c" break; - case 130: -#line 438 "parse.y" -{ yygotominor.yy284 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy98,&yymsp[-1].minor.yy98); } -#line 2270 "parse.c" + case 100: +#line 338 "parse.y" +{ + if( yymsp[0].minor.yy91 ){ + yymsp[0].minor.yy91->op = yymsp[-1].minor.yy328; + yymsp[0].minor.yy91->pPrior = yymsp[-2].minor.yy91; + } + yygotominor.yy91 = yymsp[0].minor.yy91; +} +#line 2283 "parse.c" break; - case 131: - case 139: - case 148: - case 155: - case 226: - case 228: - case 232: -#line 442 "parse.y" -{yygotominor.yy258 = yymsp[0].minor.yy258;} -#line 2281 "parse.c" + case 102: +#line 347 "parse.y" +{yygotominor.yy328 = TK_ALL;} +#line 2288 "parse.c" break; - case 132: + case 105: +#line 352 "parse.y" +{ + yygotominor.yy91 = sqlite3SelectNew(yymsp[-6].minor.yy322,yymsp[-5].minor.yy439,yymsp[-4].minor.yy418,yymsp[-3].minor.yy322,yymsp[-2].minor.yy418,yymsp[-1].minor.yy322,yymsp[-7].minor.yy328,yymsp[0].minor.yy388.pLimit,yymsp[0].minor.yy388.pOffset); +} +#line 2295 "parse.c" + break; + case 109: + case 248: +#line 373 "parse.y" +{yygotominor.yy322 = yymsp[-1].minor.yy322;} +#line 2301 "parse.c" + break; + case 110: + case 137: case 147: - case 154: - case 227: - case 229: - case 233: -#line 443 "parse.y" -{yygotominor.yy258 = 0;} -#line 2291 "parse.c" - break; - case 133: - case 166: -#line 447 "parse.y" -{yygotominor.yy272 = yymsp[-1].minor.yy272;} -#line 2297 "parse.c" - break; - case 134: - case 165: -#line 448 "parse.y" -{yygotominor.yy272 = 0;} -#line 2303 "parse.c" - break; - case 136: - case 146: -#line 459 "parse.y" -{yygotominor.yy210 = yymsp[0].minor.yy210;} + case 247: +#line 374 "parse.y" +{yygotominor.yy322 = 0;} #line 2309 "parse.c" break; - case 137: -#line 460 "parse.y" + case 111: +#line 375 "parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210,yymsp[-2].minor.yy258,yymsp[-1].minor.yy98.n>0?&yymsp[-1].minor.yy98:0); - if( yygotominor.yy210 ) yygotominor.yy210->a[yygotominor.yy210->nExpr-1].sortOrder = yymsp[0].minor.yy284; + yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-2].minor.yy322,yymsp[-1].minor.yy418,yymsp[0].minor.yy430.n?&yymsp[0].minor.yy430:0); } -#line 2317 "parse.c" +#line 2316 "parse.c" break; - case 138: -#line 464 "parse.y" + case 112: +#line 378 "parse.y" { - yygotominor.yy210 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy258,yymsp[-1].minor.yy98.n>0?&yymsp[-1].minor.yy98:0); - if( yygotominor.yy210 && yygotominor.yy210->a ) yygotominor.yy210->a[0].sortOrder = yymsp[0].minor.yy284; + yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-1].minor.yy322, sqlite3Expr(TK_ALL, 0, 0, 0), 0); } -#line 2325 "parse.c" +#line 2323 "parse.c" break; - case 140: - case 142: -#line 473 "parse.y" -{yygotominor.yy284 = SQLITE_SO_ASC;} -#line 2331 "parse.c" + case 113: +#line 381 "parse.y" +{ + Expr *pRight = sqlite3Expr(TK_ALL, 0, 0, 0); + Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy430); + yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-3].minor.yy322, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0); +} +#line 2332 "parse.c" break; - case 141: -#line 474 "parse.y" -{yygotominor.yy284 = SQLITE_SO_DESC;} -#line 2336 "parse.c" + case 116: +#line 393 "parse.y" +{yygotominor.yy430.n = 0;} +#line 2337 "parse.c" break; - case 143: -#line 476 "parse.y" -{yygotominor.yy98.z = 0; yygotominor.yy98.n = 0;} -#line 2341 "parse.c" + case 117: +#line 405 "parse.y" +{yygotominor.yy439 = sqliteMalloc(sizeof(*yygotominor.yy439));} +#line 2342 "parse.c" break; - case 149: -#line 490 "parse.y" -{yygotominor.yy404.limit = -1; yygotominor.yy404.offset = 0;} -#line 2346 "parse.c" + case 118: +#line 406 "parse.y" +{yygotominor.yy439 = yymsp[0].minor.yy439;} +#line 2347 "parse.c" break; - case 150: -#line 491 "parse.y" -{yygotominor.yy404.limit = yymsp[0].minor.yy284; yygotominor.yy404.offset = 0;} -#line 2351 "parse.c" + case 119: +#line 411 "parse.y" +{ + yygotominor.yy439 = yymsp[-1].minor.yy439; + if( yygotominor.yy439 && yygotominor.yy439->nSrc>0 ) yygotominor.yy439->a[yygotominor.yy439->nSrc-1].jointype = yymsp[0].minor.yy328; +} +#line 2355 "parse.c" break; - case 151: -#line 493 "parse.y" -{yygotominor.yy404.limit = yymsp[-2].minor.yy284; yygotominor.yy404.offset = yymsp[0].minor.yy284;} -#line 2356 "parse.c" + case 120: +#line 415 "parse.y" +{yygotominor.yy439 = 0;} +#line 2360 "parse.c" break; - case 152: -#line 495 "parse.y" -{yygotominor.yy404.limit = yymsp[0].minor.yy284; yygotominor.yy404.offset = yymsp[-2].minor.yy284;} -#line 2361 "parse.c" - break; - case 153: -#line 499 "parse.y" -{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy259,yymsp[0].minor.yy258);} -#line 2366 "parse.c" - break; - case 156: -#line 513 "parse.y" -{sqlite3Update(pParse,yymsp[-3].minor.yy259,yymsp[-1].minor.yy210,yymsp[0].minor.yy258,yymsp[-4].minor.yy284);} -#line 2371 "parse.c" - break; - case 157: -#line 516 "parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210,yymsp[0].minor.yy258,&yymsp[-2].minor.yy98);} + case 121: +#line 416 "parse.y" +{ + yygotominor.yy439 = sqlite3SrcListAppend(yymsp[-5].minor.yy439,&yymsp[-4].minor.yy430,&yymsp[-3].minor.yy430); + if( yymsp[-2].minor.yy430.n ) sqlite3SrcListAddAlias(yygotominor.yy439,&yymsp[-2].minor.yy430); + if( yymsp[-1].minor.yy418 ){ + if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pOn = yymsp[-1].minor.yy418; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy418); } + } + if( yymsp[0].minor.yy232 ){ + if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pUsing = yymsp[0].minor.yy232; } + else { sqlite3IdListDelete(yymsp[0].minor.yy232); } + } +} #line 2376 "parse.c" break; + case 122: +#line 430 "parse.y" +{ + yygotominor.yy439 = sqlite3SrcListAppend(yymsp[-6].minor.yy439,0,0); + yygotominor.yy439->a[yygotominor.yy439->nSrc-1].pSelect = yymsp[-4].minor.yy91; + if( yymsp[-2].minor.yy430.n ) sqlite3SrcListAddAlias(yygotominor.yy439,&yymsp[-2].minor.yy430); + if( yymsp[-1].minor.yy418 ){ + if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pOn = yymsp[-1].minor.yy418; } + else { sqlite3ExprDelete(yymsp[-1].minor.yy418); } + } + if( yymsp[0].minor.yy232 ){ + if( yygotominor.yy439 && yygotominor.yy439->nSrc>1 ){ yygotominor.yy439->a[yygotominor.yy439->nSrc-2].pUsing = yymsp[0].minor.yy232; } + else { sqlite3IdListDelete(yymsp[0].minor.yy232); } + } + } +#line 2393 "parse.c" + break; + case 124: +#line 451 "parse.y" +{ + yygotominor.yy91 = sqlite3SelectNew(0,yymsp[0].minor.yy439,0,0,0,0,0,0,0); + } +#line 2400 "parse.c" + break; + case 125: +#line 457 "parse.y" +{yygotominor.yy430.z=0; yygotominor.yy430.n=0;} +#line 2405 "parse.c" + break; + case 127: +#line 462 "parse.y" +{yygotominor.yy439 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430);} +#line 2410 "parse.c" + break; + case 128: + case 129: +#line 466 "parse.y" +{ yygotominor.yy328 = JT_INNER; } +#line 2416 "parse.c" + break; + case 130: +#line 468 "parse.y" +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +#line 2421 "parse.c" + break; + case 131: +#line 469 "parse.y" +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy430,0); } +#line 2426 "parse.c" + break; + case 132: +#line 471 "parse.y" +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy430,&yymsp[-1].minor.yy430); } +#line 2431 "parse.c" + break; + case 133: + case 141: + case 150: + case 157: + case 171: + case 211: + case 236: + case 238: + case 242: +#line 475 "parse.y" +{yygotominor.yy418 = yymsp[0].minor.yy418;} +#line 2444 "parse.c" + break; + case 134: + case 149: + case 156: + case 212: + case 237: + case 239: + case 243: +#line 476 "parse.y" +{yygotominor.yy418 = 0;} +#line 2455 "parse.c" + break; + case 135: + case 168: +#line 480 "parse.y" +{yygotominor.yy232 = yymsp[-1].minor.yy232;} +#line 2461 "parse.c" + break; + case 136: + case 167: +#line 481 "parse.y" +{yygotominor.yy232 = 0;} +#line 2467 "parse.c" + break; + case 138: + case 148: +#line 492 "parse.y" +{yygotominor.yy322 = yymsp[0].minor.yy322;} +#line 2473 "parse.c" + break; + case 139: +#line 493 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322,yymsp[-2].minor.yy418,yymsp[-1].minor.yy430.n>0?&yymsp[-1].minor.yy430:0); + if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = yymsp[0].minor.yy328; +} +#line 2481 "parse.c" + break; + case 140: +#line 497 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy418,yymsp[-1].minor.yy430.n>0?&yymsp[-1].minor.yy430:0); + if( yygotominor.yy322 && yygotominor.yy322->a ) yygotominor.yy322->a[0].sortOrder = yymsp[0].minor.yy328; +} +#line 2489 "parse.c" + break; + case 142: + case 144: +#line 506 "parse.y" +{yygotominor.yy328 = SQLITE_SO_ASC;} +#line 2495 "parse.c" + break; + case 143: +#line 507 "parse.y" +{yygotominor.yy328 = SQLITE_SO_DESC;} +#line 2500 "parse.c" + break; + case 145: +#line 509 "parse.y" +{yygotominor.yy430.z = 0; yygotominor.yy430.n = 0;} +#line 2505 "parse.c" + break; + case 151: +#line 527 "parse.y" +{yygotominor.yy388.pLimit = 0; yygotominor.yy388.pOffset = 0;} +#line 2510 "parse.c" + break; + case 152: +#line 528 "parse.y" +{yygotominor.yy388.pLimit = yymsp[0].minor.yy418; yygotominor.yy388.pOffset = 0;} +#line 2515 "parse.c" + break; + case 153: +#line 530 "parse.y" +{yygotominor.yy388.pLimit = yymsp[-2].minor.yy418; yygotominor.yy388.pOffset = yymsp[0].minor.yy418;} +#line 2520 "parse.c" + break; + case 154: +#line 532 "parse.y" +{yygotominor.yy388.pOffset = yymsp[-2].minor.yy418; yygotominor.yy388.pLimit = yymsp[0].minor.yy418;} +#line 2525 "parse.c" + break; + case 155: +#line 536 "parse.y" +{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy439,yymsp[0].minor.yy418);} +#line 2530 "parse.c" + break; case 158: -#line 517 "parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(0,yymsp[0].minor.yy258,&yymsp[-2].minor.yy98);} -#line 2381 "parse.c" +#line 550 "parse.y" +{sqlite3Update(pParse,yymsp[-3].minor.yy439,yymsp[-1].minor.yy322,yymsp[0].minor.yy418,yymsp[-4].minor.yy328);} +#line 2535 "parse.c" break; case 159: -#line 523 "parse.y" -{sqlite3Insert(pParse, yymsp[-5].minor.yy259, yymsp[-1].minor.yy210, 0, yymsp[-4].minor.yy272, yymsp[-7].minor.yy284);} -#line 2386 "parse.c" +#line 553 "parse.y" +{yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322,yymsp[0].minor.yy418,&yymsp[-2].minor.yy430);} +#line 2540 "parse.c" break; case 160: -#line 525 "parse.y" -{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy107, yymsp[-1].minor.yy272, yymsp[-4].minor.yy284);} -#line 2391 "parse.c" +#line 554 "parse.y" +{yygotominor.yy322 = sqlite3ExprListAppend(0,yymsp[0].minor.yy418,&yymsp[-2].minor.yy430);} +#line 2545 "parse.c" break; - case 163: - case 230: -#line 535 "parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-2].minor.yy210,yymsp[0].minor.yy258,0);} -#line 2397 "parse.c" + case 161: +#line 560 "parse.y" +{sqlite3Insert(pParse, yymsp[-5].minor.yy439, yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy232, yymsp[-7].minor.yy328);} +#line 2550 "parse.c" break; - case 164: - case 231: -#line 536 "parse.y" -{yygotominor.yy210 = sqlite3ExprListAppend(0,yymsp[0].minor.yy258,0);} -#line 2403 "parse.c" + case 162: +#line 562 "parse.y" +{sqlite3Insert(pParse, yymsp[-2].minor.yy439, 0, yymsp[0].minor.yy91, yymsp[-1].minor.yy232, yymsp[-4].minor.yy328);} +#line 2555 "parse.c" break; - case 167: -#line 545 "parse.y" -{yygotominor.yy272 = sqlite3IdListAppend(yymsp[-2].minor.yy272,&yymsp[0].minor.yy98);} -#line 2408 "parse.c" + case 165: + case 240: +#line 572 "parse.y" +{yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy418,0);} +#line 2561 "parse.c" break; - case 168: -#line 546 "parse.y" -{yygotominor.yy272 = sqlite3IdListAppend(0,&yymsp[0].minor.yy98);} -#line 2413 "parse.c" + case 166: + case 241: +#line 573 "parse.y" +{yygotominor.yy322 = sqlite3ExprListAppend(0,yymsp[0].minor.yy418,0);} +#line 2567 "parse.c" break; case 169: -#line 554 "parse.y" -{yygotominor.yy258 = yymsp[-1].minor.yy258; sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } -#line 2418 "parse.c" +#line 582 "parse.y" +{yygotominor.yy232 = sqlite3IdListAppend(yymsp[-2].minor.yy232,&yymsp[0].minor.yy430);} +#line 2572 "parse.c" break; case 170: - case 175: - case 176: - case 177: - case 178: -#line 555 "parse.y" -{yygotominor.yy258 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} -#line 2427 "parse.c" +#line 583 "parse.y" +{yygotominor.yy232 = sqlite3IdListAppend(0,&yymsp[0].minor.yy430);} +#line 2577 "parse.c" break; - case 171: case 172: -#line 556 "parse.y" -{yygotominor.yy258 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} -#line 2433 "parse.c" +#line 594 "parse.y" +{yygotominor.yy418 = yymsp[-1].minor.yy418; sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } +#line 2582 "parse.c" break; case 173: -#line 558 "parse.y" -{ - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy98); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy98); - yygotominor.yy258 = sqlite3Expr(TK_DOT, temp1, temp2, 0); -} -#line 2442 "parse.c" + case 178: + case 179: + case 180: + case 181: +#line 595 "parse.y" +{yygotominor.yy418 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);} +#line 2591 "parse.c" break; case 174: -#line 563 "parse.y" + case 175: +#line 596 "parse.y" +{yygotominor.yy418 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);} +#line 2597 "parse.c" + break; + case 176: +#line 598 "parse.y" { - Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy98); - Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy98); - Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy98); + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy430); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy430); + yygotominor.yy418 = sqlite3Expr(TK_DOT, temp1, temp2, 0); +} +#line 2606 "parse.c" + break; + case 177: +#line 603 "parse.y" +{ + Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy430); + Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy430); + Expr *temp3 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy430); Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0); - yygotominor.yy258 = sqlite3Expr(TK_DOT, temp1, temp4, 0); + yygotominor.yy418 = sqlite3Expr(TK_DOT, temp1, temp4, 0); } -#line 2453 "parse.c" - break; - case 179: -#line 574 "parse.y" -{ - Token *pToken = &yymsp[0].minor.yy0; - Expr *pExpr = yygotominor.yy258 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); - sqlite3ExprAssignVarNumber(pParse, pExpr); -} -#line 2462 "parse.c" - break; - case 180: -#line 579 "parse.y" -{ - yygotominor.yy258 = sqlite3ExprFunction(yymsp[-1].minor.yy210, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); -} -#line 2470 "parse.c" - break; - case 181: -#line 583 "parse.y" -{ - yygotominor.yy258 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); -} -#line 2478 "parse.c" +#line 2617 "parse.c" break; case 182: +#line 614 "parse.y" +{yygotominor.yy418 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);} +#line 2622 "parse.c" + break; case 183: +#line 615 "parse.y" +{ + Token *pToken = &yymsp[0].minor.yy0; + Expr *pExpr = yygotominor.yy418 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken); + sqlite3ExprAssignVarNumber(pParse, pExpr); +} +#line 2631 "parse.c" + break; case 184: +#line 620 "parse.y" +{ + yygotominor.yy418 = sqlite3ExprFunction(yymsp[-1].minor.yy322, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2639 "parse.c" + break; case 185: +#line 624 "parse.y" +{ + yygotominor.yy418 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); +} +#line 2647 "parse.c" + break; case 186: case 187: case 188: +#line 628 "parse.y" +{yygotominor.yy418 = sqlite3Expr(yymsp[0].major,0,0,0);} +#line 2654 "parse.c" + break; case 189: case 190: case 191: @@ -2493,443 +2662,517 @@ static void yy_reduce( case 197: case 198: case 199: -#line 587 "parse.y" -{yygotominor.yy258 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy258, yymsp[0].minor.yy258, 0);} -#line 2500 "parse.c" - break; case 200: -#line 606 "parse.y" -{yygotominor.yy342.opcode = TK_LIKE; yygotominor.yy342.not = 0;} -#line 2505 "parse.c" - break; case 201: -#line 607 "parse.y" -{yygotominor.yy342.opcode = TK_GLOB; yygotominor.yy342.not = 0;} -#line 2510 "parse.c" - break; case 202: -#line 608 "parse.y" -{yygotominor.yy342.opcode = TK_LIKE; yygotominor.yy342.not = 1;} -#line 2515 "parse.c" - break; case 203: -#line 609 "parse.y" -{yygotominor.yy342.opcode = TK_GLOB; yygotominor.yy342.not = 1;} -#line 2520 "parse.c" - break; case 204: -#line 610 "parse.y" -{ - ExprList *pList = sqlite3ExprListAppend(0, yymsp[0].minor.yy258, 0); - pList = sqlite3ExprListAppend(pList, yymsp[-2].minor.yy258, 0); - yygotominor.yy258 = sqlite3ExprFunction(pList, 0); - if( yygotominor.yy258 ) yygotominor.yy258->op = yymsp[-1].minor.yy342.opcode; - if( yymsp[-1].minor.yy342.not ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-2].minor.yy258->span, &yymsp[0].minor.yy258->span); -} -#line 2532 "parse.c" - break; case 205: -#line 618 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2540 "parse.c" - break; case 206: -#line 622 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2548 "parse.c" +#line 631 "parse.y" +{yygotominor.yy418 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy418, yymsp[0].minor.yy418, 0);} +#line 2676 "parse.c" break; case 207: -#line 626 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2556 "parse.c" +#line 650 "parse.y" +{yygotominor.yy30.opcode = TK_LIKE; yygotominor.yy30.not = 0;} +#line 2681 "parse.c" break; case 208: -#line 630 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2564 "parse.c" +#line 651 "parse.y" +{yygotominor.yy30.opcode = TK_GLOB; yygotominor.yy30.not = 0;} +#line 2686 "parse.c" break; case 209: -#line 634 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy258->span,&yymsp[0].minor.yy0); -} -#line 2572 "parse.c" +#line 652 "parse.y" +{yygotominor.yy30.opcode = TK_LIKE; yygotominor.yy30.not = 1;} +#line 2691 "parse.c" break; case 210: - case 211: -#line 638 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy258->span); -} -#line 2581 "parse.c" - break; - case 212: -#line 646 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy258->span); -} -#line 2589 "parse.c" +#line 653 "parse.y" +{yygotominor.yy30.opcode = TK_GLOB; yygotominor.yy30.not = 1;} +#line 2696 "parse.c" break; case 213: -#line 650 "parse.y" +#line 657 "parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy258->span); + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy418, 0); + pList = sqlite3ExprListAppend(pList, yymsp[-3].minor.yy418, 0); + if( yymsp[0].minor.yy418 ){ + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy418, 0); + } + yygotominor.yy418 = sqlite3ExprFunction(pList, 0); + if( yygotominor.yy418 ) yygotominor.yy418->op = yymsp[-2].minor.yy30.opcode; + if( yymsp[-2].minor.yy30.not ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418, &yymsp[-3].minor.yy418->span, &yymsp[-1].minor.yy418->span); } -#line 2597 "parse.c" +#line 2711 "parse.c" break; case 214: -#line 654 "parse.y" +#line 669 "parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_SELECT, 0, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pSelect = yymsp[-1].minor.yy107; - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy418 = sqlite3Expr(TK_ISNULL, yymsp[-1].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy418->span,&yymsp[0].minor.yy0); } -#line 2606 "parse.c" +#line 2719 "parse.c" break; - case 217: -#line 662 "parse.y" -{ - ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy258, 0); - pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy258, 0); - yygotominor.yy258 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pList = pList; - if( yymsp[-3].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-4].minor.yy258->span,&yymsp[0].minor.yy258->span); -} -#line 2618 "parse.c" - break; - case 220: + case 215: #line 673 "parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pList = yymsp[-1].minor.yy210; - if( yymsp[-3].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-4].minor.yy258->span,&yymsp[0].minor.yy0); + yygotominor.yy418 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy418->span,&yymsp[0].minor.yy0); } -#line 2628 "parse.c" +#line 2727 "parse.c" break; - case 221: -#line 679 "parse.y" + case 216: +#line 677 "parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pSelect = yymsp[-1].minor.yy107; - if( yymsp[-3].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-4].minor.yy258->span,&yymsp[0].minor.yy0); + yygotominor.yy418 = sqlite3Expr(TK_NOTNULL, yymsp[-1].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy418->span,&yymsp[0].minor.yy0); } -#line 2638 "parse.c" - break; - case 222: -#line 685 "parse.y" -{ - SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98); - yygotominor.yy258 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy258, 0, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,-1,0); - if( yymsp[-2].minor.yy284 ) yygotominor.yy258 = sqlite3Expr(TK_NOT, yygotominor.yy258, 0, 0); - sqlite3ExprSpan(yygotominor.yy258,&yymsp[-3].minor.yy258->span,yymsp[0].minor.yy98.z?&yymsp[0].minor.yy98:&yymsp[-1].minor.yy98); -} -#line 2649 "parse.c" - break; - case 223: -#line 695 "parse.y" -{ - yygotominor.yy258 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy258, yymsp[-1].minor.yy258, 0); - if( yygotominor.yy258 ) yygotominor.yy258->pList = yymsp[-2].minor.yy210; - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); -} -#line 2658 "parse.c" - break; - case 224: -#line 702 "parse.y" -{ - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210, yymsp[-2].minor.yy258, 0); - yygotominor.yy210 = sqlite3ExprListAppend(yygotominor.yy210, yymsp[0].minor.yy258, 0); -} -#line 2666 "parse.c" - break; - case 225: -#line 706 "parse.y" -{ - yygotominor.yy210 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy258, 0); - yygotominor.yy210 = sqlite3ExprListAppend(yygotominor.yy210, yymsp[0].minor.yy258, 0); -} -#line 2674 "parse.c" - break; - case 234: -#line 731 "parse.y" -{ - if( yymsp[-9].minor.yy284!=OE_None ) yymsp[-9].minor.yy284 = yymsp[0].minor.yy284; - if( yymsp[-9].minor.yy284==OE_Default) yymsp[-9].minor.yy284 = OE_Abort; - sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy98, &yymsp[-6].minor.yy98, yymsp[-4].minor.yy259, yymsp[-2].minor.yy210, yymsp[-9].minor.yy284, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); -} -#line 2683 "parse.c" - break; - case 235: - case 282: -#line 738 "parse.y" -{yygotominor.yy284 = OE_Abort;} -#line 2689 "parse.c" - break; - case 236: -#line 739 "parse.y" -{yygotominor.yy284 = OE_None;} -#line 2694 "parse.c" - break; - case 239: -#line 749 "parse.y" -{ - Expr *p = 0; - if( yymsp[-1].minor.yy98.n>0 ){ - p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy98.z, yymsp[-1].minor.yy98.n); - } - yygotominor.yy210 = sqlite3ExprListAppend(yymsp[-4].minor.yy210, p, &yymsp[-2].minor.yy98); -} -#line 2706 "parse.c" - break; - case 240: -#line 757 "parse.y" -{ - Expr *p = 0; - if( yymsp[-1].minor.yy98.n>0 ){ - p = sqlite3Expr(TK_COLUMN, 0, 0, 0); - if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy98.z, yymsp[-1].minor.yy98.n); - } - yygotominor.yy210 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy98); -} -#line 2718 "parse.c" - break; - case 242: -#line 770 "parse.y" -{sqlite3DropIndex(pParse, yymsp[0].minor.yy259);} -#line 2723 "parse.c" - break; - case 243: - case 244: -#line 774 "parse.y" -{sqlite3Vacuum(pParse,0);} -#line 2729 "parse.c" - break; - case 245: - case 247: -#line 779 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy98,&yymsp[-2].minor.yy98,&yymsp[0].minor.yy98,0);} #line 2735 "parse.c" break; - case 246: -#line 780 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-3].minor.yy98,&yymsp[-2].minor.yy98,&yymsp[0].minor.yy0,0);} -#line 2740 "parse.c" - break; - case 248: -#line 782 "parse.y" + case 217: +#line 681 "parse.y" { - sqlite3Pragma(pParse,&yymsp[-3].minor.yy98,&yymsp[-2].minor.yy98,&yymsp[0].minor.yy98,1); + yygotominor.yy418 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy418->span,&yymsp[0].minor.yy0); } -#line 2747 "parse.c" +#line 2743 "parse.c" break; - case 249: -#line 785 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-4].minor.yy98,&yymsp[-3].minor.yy98,&yymsp[-1].minor.yy98,0);} -#line 2752 "parse.c" - break; - case 250: -#line 786 "parse.y" -{sqlite3Pragma(pParse,&yymsp[-1].minor.yy98,&yymsp[0].minor.yy98,0,0);} -#line 2757 "parse.c" - break; - case 257: -#line 796 "parse.y" + case 218: +#line 685 "parse.y" { - Token all; - all.z = yymsp[-3].minor.yy98.z; - all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy98.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy91, &all); + yygotominor.yy418 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy418->span,&yymsp[0].minor.yy0); } -#line 2767 "parse.c" +#line 2751 "parse.c" break; - case 258: -#line 805 "parse.y" + case 219: + case 220: +#line 689 "parse.y" { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy98, &yymsp[-6].minor.yy98, yymsp[-5].minor.yy284, yymsp[-4].minor.yy146.a, yymsp[-4].minor.yy146.b, yymsp[-2].minor.yy259, yymsp[-1].minor.yy284, yymsp[0].minor.yy258, yymsp[-9].minor.yy284); - yygotominor.yy98 = (yymsp[-6].minor.yy98.n==0?yymsp[-7].minor.yy98:yymsp[-6].minor.yy98); + yygotominor.yy418 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy418->span); } -#line 2775 "parse.c" +#line 2760 "parse.c" break; - case 259: - case 262: -#line 811 "parse.y" -{ yygotominor.yy284 = TK_BEFORE; } -#line 2781 "parse.c" - break; - case 260: -#line 812 "parse.y" -{ yygotominor.yy284 = TK_AFTER; } -#line 2786 "parse.c" - break; - case 261: -#line 813 "parse.y" -{ yygotominor.yy284 = TK_INSTEAD;} -#line 2791 "parse.c" - break; - case 263: - case 264: - case 265: -#line 818 "parse.y" -{yygotominor.yy146.a = yymsp[0].major; yygotominor.yy146.b = 0;} -#line 2798 "parse.c" - break; - case 266: -#line 821 "parse.y" -{yygotominor.yy146.a = TK_UPDATE; yygotominor.yy146.b = yymsp[0].minor.yy272;} -#line 2803 "parse.c" - break; - case 267: - case 268: -#line 824 "parse.y" -{ yygotominor.yy284 = TK_ROW; } -#line 2809 "parse.c" - break; - case 269: -#line 826 "parse.y" -{ yygotominor.yy284 = TK_STATEMENT; } -#line 2814 "parse.c" - break; - case 270: -#line 829 "parse.y" -{ yygotominor.yy258 = 0; } -#line 2819 "parse.c" - break; - case 271: -#line 830 "parse.y" -{ yygotominor.yy258 = yymsp[0].minor.yy258; } -#line 2824 "parse.c" - break; - case 272: -#line 834 "parse.y" + case 221: +#line 697 "parse.y" { - yymsp[-2].minor.yy91->pNext = yymsp[0].minor.yy91; - yygotominor.yy91 = yymsp[-2].minor.yy91; + yygotominor.yy418 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy418->span); } -#line 2832 "parse.c" +#line 2768 "parse.c" break; - case 273: -#line 838 "parse.y" -{ yygotominor.yy91 = 0; } -#line 2837 "parse.c" - break; - case 274: -#line 844 "parse.y" -{ yygotominor.yy91 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy98, yymsp[-1].minor.yy210, yymsp[0].minor.yy258, yymsp[-4].minor.yy284); } -#line 2842 "parse.c" - break; - case 275: -#line 849 "parse.y" -{yygotominor.yy91 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy98, yymsp[-4].minor.yy272, yymsp[-1].minor.yy210, 0, yymsp[-7].minor.yy284);} -#line 2847 "parse.c" - break; - case 276: -#line 852 "parse.y" -{yygotominor.yy91 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy98, yymsp[-1].minor.yy272, 0, yymsp[0].minor.yy107, yymsp[-4].minor.yy284);} -#line 2852 "parse.c" - break; - case 277: -#line 856 "parse.y" -{yygotominor.yy91 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy98, yymsp[0].minor.yy258);} -#line 2857 "parse.c" - break; - case 278: -#line 859 "parse.y" -{yygotominor.yy91 = sqlite3TriggerSelectStep(yymsp[0].minor.yy107); } -#line 2862 "parse.c" - break; - case 279: -#line 862 "parse.y" + case 222: +#line 701 "parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_RAISE, 0, 0, 0); - yygotominor.yy258->iColumn = OE_Ignore; - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); + yygotominor.yy418 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy418->span); +} +#line 2776 "parse.c" + break; + case 225: +#line 708 "parse.y" +{ + ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy418, 0); + pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy418, 0); + yygotominor.yy418 = sqlite3Expr(TK_BETWEEN, yymsp[-4].minor.yy418, 0, 0); + if( yygotominor.yy418 ) yygotominor.yy418->pList = pList; + if( yymsp[-3].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-4].minor.yy418->span,&yymsp[0].minor.yy418->span); +} +#line 2788 "parse.c" + break; + case 228: +#line 720 "parse.y" +{ + yygotominor.yy418 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy418, 0, 0); + if( yygotominor.yy418 ){ + yygotominor.yy418->pList = yymsp[-1].minor.yy322; + }else{ + sqlite3ExprListDelete(yymsp[-1].minor.yy322); + } + if( yymsp[-3].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-4].minor.yy418->span,&yymsp[0].minor.yy0); + } +#line 2802 "parse.c" + break; + case 229: +#line 730 "parse.y" +{ + yygotominor.yy418 = sqlite3Expr(TK_SELECT, 0, 0, 0); + if( yygotominor.yy418 ) yygotominor.yy418->pSelect = yymsp[-1].minor.yy91; + if( !yygotominor.yy418 ) sqlite3SelectDelete(yymsp[-1].minor.yy91); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + } +#line 2812 "parse.c" + break; + case 230: +#line 736 "parse.y" +{ + yygotominor.yy418 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy418, 0, 0); + if( yygotominor.yy418 ) yygotominor.yy418->pSelect = yymsp[-1].minor.yy91; + if( !yygotominor.yy418 ) sqlite3SelectDelete(yymsp[-1].minor.yy91); + if( yymsp[-3].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-4].minor.yy418->span,&yymsp[0].minor.yy0); + } +#line 2823 "parse.c" + break; + case 231: +#line 743 "parse.y" +{ + SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430); + yygotominor.yy418 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy418, 0, 0); + if( yygotominor.yy418 ) yygotominor.yy418->pSelect = sqlite3SelectNew(0,pSrc,0,0,0,0,0,0,0); + if( yymsp[-2].minor.yy328 ) yygotominor.yy418 = sqlite3Expr(TK_NOT, yygotominor.yy418, 0, 0); + sqlite3ExprSpan(yygotominor.yy418,&yymsp[-3].minor.yy418->span,yymsp[0].minor.yy430.z?&yymsp[0].minor.yy430:&yymsp[-1].minor.yy430); + } +#line 2834 "parse.c" + break; + case 232: +#line 750 "parse.y" +{ + Expr *p = yygotominor.yy418 = sqlite3Expr(TK_EXISTS, 0, 0, 0); + if( p ){ + p->pSelect = yymsp[-1].minor.yy91; + sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + } + if( !p ) sqlite3SelectDelete(yymsp[-1].minor.yy91); + } +#line 2846 "parse.c" + break; + case 233: +#line 761 "parse.y" +{ + yygotominor.yy418 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy418, yymsp[-1].minor.yy418, 0); + if( yygotominor.yy418 ) yygotominor.yy418->pList = yymsp[-2].minor.yy322; + sqlite3ExprSpan(yygotominor.yy418, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0); +} +#line 2855 "parse.c" + break; + case 234: +#line 768 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322, yymsp[-2].minor.yy418, 0); + yygotominor.yy322 = sqlite3ExprListAppend(yygotominor.yy322, yymsp[0].minor.yy418, 0); +} +#line 2863 "parse.c" + break; + case 235: +#line 772 "parse.y" +{ + yygotominor.yy322 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy418, 0); + yygotominor.yy322 = sqlite3ExprListAppend(yygotominor.yy322, yymsp[0].minor.yy418, 0); } #line 2871 "parse.c" break; - case 280: -#line 867 "parse.y" + case 244: +#line 797 "parse.y" { - yygotominor.yy258 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy98); - yygotominor.yy258->iColumn = yymsp[-3].minor.yy284; - sqlite3ExprSpan(yygotominor.yy258, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); + if( yymsp[-9].minor.yy328!=OE_None ) yymsp[-9].minor.yy328 = yymsp[0].minor.yy328; + if( yymsp[-9].minor.yy328==OE_Default) yymsp[-9].minor.yy328 = OE_Abort; + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy430, &yymsp[-6].minor.yy430, sqlite3SrcListAppend(0,&yymsp[-4].minor.yy430,0),yymsp[-2].minor.yy322,yymsp[-9].minor.yy328, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0); } #line 2880 "parse.c" break; + case 245: + case 292: +#line 804 "parse.y" +{yygotominor.yy328 = OE_Abort;} +#line 2886 "parse.c" + break; + case 246: +#line 805 "parse.y" +{yygotominor.yy328 = OE_None;} +#line 2891 "parse.c" + break; + case 249: +#line 815 "parse.y" +{ + Expr *p = 0; + if( yymsp[-1].minor.yy430.n>0 ){ + p = sqlite3Expr(TK_COLUMN, 0, 0, 0); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy430.z, yymsp[-1].minor.yy430.n); + } + yygotominor.yy322 = sqlite3ExprListAppend(yymsp[-4].minor.yy322, p, &yymsp[-2].minor.yy430); +} +#line 2903 "parse.c" + break; + case 250: +#line 823 "parse.y" +{ + Expr *p = 0; + if( yymsp[-1].minor.yy430.n>0 ){ + p = sqlite3Expr(TK_COLUMN, 0, 0, 0); + if( p ) p->pColl = sqlite3LocateCollSeq(pParse, yymsp[-1].minor.yy430.z, yymsp[-1].minor.yy430.n); + } + yygotominor.yy322 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy430); +} +#line 2915 "parse.c" + break; + case 252: +#line 836 "parse.y" +{sqlite3DropIndex(pParse, yymsp[0].minor.yy439);} +#line 2920 "parse.c" + break; + case 253: + case 254: +#line 840 "parse.y" +{sqlite3Vacuum(pParse,0);} +#line 2926 "parse.c" + break; + case 255: + case 257: +#line 846 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy430,&yymsp[-2].minor.yy430,&yymsp[0].minor.yy430,0);} +#line 2932 "parse.c" + break; + case 256: +#line 847 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy430,&yymsp[-2].minor.yy430,&yymsp[0].minor.yy0,0);} +#line 2937 "parse.c" + break; + case 258: +#line 849 "parse.y" +{ + sqlite3Pragma(pParse,&yymsp[-3].minor.yy430,&yymsp[-2].minor.yy430,&yymsp[0].minor.yy430,1); +} +#line 2944 "parse.c" + break; + case 259: +#line 852 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy430,&yymsp[-3].minor.yy430,&yymsp[-1].minor.yy430,0);} +#line 2949 "parse.c" + break; + case 260: +#line 853 "parse.y" +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy430,&yymsp[0].minor.yy430,0,0);} +#line 2954 "parse.c" + break; + case 267: +#line 866 "parse.y" +{ + Token all; + all.z = yymsp[-3].minor.yy430.z; + all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy430.z) + yymsp[0].minor.yy0.n; + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy451, &all); +} +#line 2964 "parse.c" + break; + case 268: +#line 875 "parse.y" +{ + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy430, &yymsp[-6].minor.yy430, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy439, yymsp[-1].minor.yy328, yymsp[0].minor.yy418, yymsp[-9].minor.yy328); + yygotominor.yy430 = (yymsp[-6].minor.yy430.n==0?yymsp[-7].minor.yy430:yymsp[-6].minor.yy430); +} +#line 2972 "parse.c" + break; + case 269: + case 272: +#line 881 "parse.y" +{ yygotominor.yy328 = TK_BEFORE; } +#line 2978 "parse.c" + break; + case 270: +#line 882 "parse.y" +{ yygotominor.yy328 = TK_AFTER; } +#line 2983 "parse.c" + break; + case 271: +#line 883 "parse.y" +{ yygotominor.yy328 = TK_INSTEAD;} +#line 2988 "parse.c" + break; + case 273: + case 274: + case 275: +#line 888 "parse.y" +{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;} +#line 2995 "parse.c" + break; + case 276: +#line 891 "parse.y" +{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy232;} +#line 3000 "parse.c" + break; + case 277: + case 278: +#line 894 "parse.y" +{ yygotominor.yy328 = TK_ROW; } +#line 3006 "parse.c" + break; + case 279: +#line 896 "parse.y" +{ yygotominor.yy328 = TK_STATEMENT; } +#line 3011 "parse.c" + break; + case 280: +#line 899 "parse.y" +{ yygotominor.yy418 = 0; } +#line 3016 "parse.c" + break; case 281: -#line 873 "parse.y" -{yygotominor.yy284 = OE_Rollback;} -#line 2885 "parse.c" +#line 900 "parse.y" +{ yygotominor.yy418 = yymsp[0].minor.yy418; } +#line 3021 "parse.c" + break; + case 282: +#line 904 "parse.y" +{ + yymsp[-2].minor.yy451->pNext = yymsp[0].minor.yy451; + yygotominor.yy451 = yymsp[-2].minor.yy451; +} +#line 3029 "parse.c" break; case 283: -#line 875 "parse.y" -{yygotominor.yy284 = OE_Fail;} -#line 2890 "parse.c" +#line 908 "parse.y" +{ yygotominor.yy451 = 0; } +#line 3034 "parse.c" break; case 284: -#line 879 "parse.y" -{ - sqlite3DropTrigger(pParse,yymsp[0].minor.yy259); -} -#line 2897 "parse.c" +#line 914 "parse.y" +{ yygotominor.yy451 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy430, yymsp[-1].minor.yy322, yymsp[0].minor.yy418, yymsp[-4].minor.yy328); } +#line 3039 "parse.c" break; case 285: -#line 884 "parse.y" -{ - sqlite3Attach(pParse, &yymsp[-3].minor.yy98, &yymsp[-1].minor.yy98, yymsp[0].minor.yy292.type, &yymsp[0].minor.yy292.key); -} -#line 2904 "parse.c" +#line 919 "parse.y" +{yygotominor.yy451 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy430, yymsp[-4].minor.yy232, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy328);} +#line 3044 "parse.c" break; case 286: -#line 888 "parse.y" -{ yygotominor.yy292.type = 0; } -#line 2909 "parse.c" +#line 922 "parse.y" +{yygotominor.yy451 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy430, yymsp[-1].minor.yy232, 0, yymsp[0].minor.yy91, yymsp[-4].minor.yy328);} +#line 3049 "parse.c" break; case 287: -#line 889 "parse.y" -{ yygotominor.yy292.type=1; yygotominor.yy292.key = yymsp[0].minor.yy98; } -#line 2914 "parse.c" +#line 926 "parse.y" +{yygotominor.yy451 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy430, yymsp[0].minor.yy418);} +#line 3054 "parse.c" break; case 288: -#line 890 "parse.y" -{ yygotominor.yy292.type=2; yygotominor.yy292.key = yymsp[0].minor.yy0; } -#line 2919 "parse.c" +#line 929 "parse.y" +{yygotominor.yy451 = sqlite3TriggerSelectStep(yymsp[0].minor.yy91); } +#line 3059 "parse.c" + break; + case 289: +#line 932 "parse.y" +{ + yygotominor.yy418 = sqlite3Expr(TK_RAISE, 0, 0, 0); + yygotominor.yy418->iColumn = OE_Ignore; + sqlite3ExprSpan(yygotominor.yy418, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0); +} +#line 3068 "parse.c" + break; + case 290: +#line 937 "parse.y" +{ + yygotominor.yy418 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy430); + yygotominor.yy418->iColumn = yymsp[-3].minor.yy328; + sqlite3ExprSpan(yygotominor.yy418, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0); +} +#line 3077 "parse.c" break; case 291: -#line 896 "parse.y" +#line 945 "parse.y" +{yygotominor.yy328 = OE_Rollback;} +#line 3082 "parse.c" + break; + case 293: +#line 947 "parse.y" +{yygotominor.yy328 = OE_Fail;} +#line 3087 "parse.c" + break; + case 294: +#line 952 "parse.y" { - sqlite3Detach(pParse, &yymsp[0].minor.yy98); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy439); } -#line 2926 "parse.c" +#line 3094 "parse.c" + break; + case 295: +#line 958 "parse.y" +{ + sqlite3Attach(pParse, &yymsp[-3].minor.yy430, &yymsp[-1].minor.yy430, yymsp[0].minor.yy92.type, &yymsp[0].minor.yy92.key); +} +#line 3101 "parse.c" + break; + case 296: +#line 962 "parse.y" +{ yygotominor.yy92.type = 0; } +#line 3106 "parse.c" + break; + case 297: +#line 963 "parse.y" +{ yygotominor.yy92.type=1; yygotominor.yy92.key = yymsp[0].minor.yy430; } +#line 3111 "parse.c" + break; + case 298: +#line 964 "parse.y" +{ yygotominor.yy92.type=2; yygotominor.yy92.key = yymsp[0].minor.yy0; } +#line 3116 "parse.c" + break; + case 301: +#line 970 "parse.y" +{ + sqlite3Detach(pParse, &yymsp[0].minor.yy430); +} +#line 3123 "parse.c" + break; + case 302: +#line 976 "parse.y" +{sqlite3Reindex(pParse, 0, 0);} +#line 3128 "parse.c" + break; + case 303: +#line 977 "parse.y" +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy430, &yymsp[0].minor.yy430);} +#line 3133 "parse.c" + break; + case 304: +#line 982 "parse.y" +{ + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy439,&yymsp[0].minor.yy430); +} +#line 3140 "parse.c" + break; + case 305: +#line 985 "parse.y" +{ + sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy430); +} +#line 3147 "parse.c" + break; + case 306: +#line 988 "parse.y" +{ + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy439); +} +#line 3154 "parse.c" break; }; yygoto = yyRuleInfo[yyruleno].lhs; yysize = yyRuleInfo[yyruleno].nrhs; yypParser->yyidx -= yysize; - yyact = yy_find_reduce_action(yypParser,yygoto); + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); if( yyact < YYNSTATE ){ - yy_shift(yypParser,yyact,yygoto,&yygotominor); +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = yyact; + yymsp->major = yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } }else if( yyact == YYNSTATE + YYNRULE + 1 ){ yy_accept(yypParser); } @@ -2972,7 +3215,7 @@ static void yy_syntax_error( sqlite3ErrorMsg(pParse, "incomplete SQL statement"); } } -#line 2978 "parse.c" +#line 3221 "parse.c" sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */ } diff --git a/db/sqlite3/src/parse.h b/db/sqlite3/src/parse.h index 547319ed705..ce51958421f 100644 --- a/db/sqlite3/src/parse.h +++ b/db/sqlite3/src/parse.h @@ -55,75 +55,88 @@ #define TK_TRIGGER 55 #define TK_VACUUM 56 #define TK_VIEW 57 -#define TK_OR 58 -#define TK_AND 59 -#define TK_NOT 60 -#define TK_IS 61 -#define TK_BETWEEN 62 -#define TK_IN 63 -#define TK_ISNULL 64 -#define TK_NOTNULL 65 -#define TK_NE 66 -#define TK_EQ 67 -#define TK_GT 68 -#define TK_LE 69 -#define TK_LT 70 -#define TK_GE 71 -#define TK_BITAND 72 -#define TK_BITOR 73 -#define TK_LSHIFT 74 -#define TK_RSHIFT 75 -#define TK_PLUS 76 -#define TK_MINUS 77 -#define TK_STAR 78 -#define TK_SLASH 79 -#define TK_REM 80 -#define TK_CONCAT 81 -#define TK_UMINUS 82 -#define TK_UPLUS 83 -#define TK_BITNOT 84 -#define TK_STRING 85 -#define TK_JOIN_KW 86 -#define TK_CONSTRAINT 87 -#define TK_DEFAULT 88 -#define TK_NULL 89 -#define TK_PRIMARY 90 -#define TK_UNIQUE 91 -#define TK_CHECK 92 -#define TK_REFERENCES 93 -#define TK_COLLATE 94 -#define TK_ON 95 -#define TK_DELETE 96 -#define TK_UPDATE 97 -#define TK_INSERT 98 -#define TK_SET 99 -#define TK_DEFERRABLE 100 -#define TK_FOREIGN 101 -#define TK_DROP 102 -#define TK_UNION 103 -#define TK_ALL 104 -#define TK_INTERSECT 105 -#define TK_EXCEPT 106 -#define TK_SELECT 107 -#define TK_DISTINCT 108 -#define TK_DOT 109 -#define TK_FROM 110 -#define TK_JOIN 111 -#define TK_USING 112 -#define TK_ORDER 113 -#define TK_BY 114 -#define TK_GROUP 115 -#define TK_HAVING 116 -#define TK_LIMIT 117 -#define TK_WHERE 118 -#define TK_INTO 119 -#define TK_VALUES 120 -#define TK_INTEGER 121 -#define TK_FLOAT 122 -#define TK_BLOB 123 -#define TK_VARIABLE 124 -#define TK_CASE 125 -#define TK_WHEN 126 -#define TK_THEN 127 -#define TK_ELSE 128 -#define TK_INDEX 129 +#define TK_REINDEX 58 +#define TK_RENAME 59 +#define TK_CDATE 60 +#define TK_CTIME 61 +#define TK_CTIMESTAMP 62 +#define TK_ALTER 63 +#define TK_OR 64 +#define TK_AND 65 +#define TK_NOT 66 +#define TK_IS 67 +#define TK_BETWEEN 68 +#define TK_IN 69 +#define TK_ISNULL 70 +#define TK_NOTNULL 71 +#define TK_NE 72 +#define TK_EQ 73 +#define TK_GT 74 +#define TK_LE 75 +#define TK_LT 76 +#define TK_GE 77 +#define TK_ESCAPE 78 +#define TK_BITAND 79 +#define TK_BITOR 80 +#define TK_LSHIFT 81 +#define TK_RSHIFT 82 +#define TK_PLUS 83 +#define TK_MINUS 84 +#define TK_STAR 85 +#define TK_SLASH 86 +#define TK_REM 87 +#define TK_CONCAT 88 +#define TK_UMINUS 89 +#define TK_UPLUS 90 +#define TK_BITNOT 91 +#define TK_STRING 92 +#define TK_JOIN_KW 93 +#define TK_CONSTRAINT 94 +#define TK_DEFAULT 95 +#define TK_NULL 96 +#define TK_PRIMARY 97 +#define TK_UNIQUE 98 +#define TK_CHECK 99 +#define TK_REFERENCES 100 +#define TK_COLLATE 101 +#define TK_AUTOINCR 102 +#define TK_ON 103 +#define TK_DELETE 104 +#define TK_UPDATE 105 +#define TK_INSERT 106 +#define TK_SET 107 +#define TK_DEFERRABLE 108 +#define TK_FOREIGN 109 +#define TK_DROP 110 +#define TK_UNION 111 +#define TK_ALL 112 +#define TK_INTERSECT 113 +#define TK_EXCEPT 114 +#define TK_SELECT 115 +#define TK_DISTINCT 116 +#define TK_DOT 117 +#define TK_FROM 118 +#define TK_JOIN 119 +#define TK_USING 120 +#define TK_ORDER 121 +#define TK_BY 122 +#define TK_GROUP 123 +#define TK_HAVING 124 +#define TK_LIMIT 125 +#define TK_WHERE 126 +#define TK_INTO 127 +#define TK_VALUES 128 +#define TK_INTEGER 129 +#define TK_FLOAT 130 +#define TK_BLOB 131 +#define TK_REGISTER 132 +#define TK_VARIABLE 133 +#define TK_EXISTS 134 +#define TK_CASE 135 +#define TK_WHEN 136 +#define TK_THEN 137 +#define TK_ELSE 138 +#define TK_INDEX 139 +#define TK_TO 140 +#define TK_ADD 141 +#define TK_COLUMNKW 142 diff --git a/db/sqlite3/src/pragma.c b/db/sqlite3/src/pragma.c index 08d49272efc..e46d374b586 100644 --- a/db/sqlite3/src/pragma.c +++ b/db/sqlite3/src/pragma.c @@ -11,32 +11,21 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.70 2004/10/06 15:41:17 drh Exp $ +** $Id: pragma.c,v 1.90 2005/02/26 18:10:44 drh Exp $ */ #include "sqliteInt.h" +#include "os.h" #include +/* Ignore this whole file if pragmas are disabled +*/ +#ifndef SQLITE_OMIT_PRAGMA + #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) # include "pager.h" # include "btree.h" #endif -/* -** Interpret the given string as a boolean value. -*/ -static int getBoolean(const u8 *z){ - static const u8 *azTrue[] = { "yes", "on", "true" }; - int i; - if( z[0]==0 ) return 0; - if( sqlite3IsNumber(z, 0, SQLITE_UTF8) ){ - return atoi(z); - } - for(i=0; idb; - if( db->temp_store==ts ) return SQLITE_OK; if( db->aDb[1].pBt!=0 ){ if( db->flags & SQLITE_InTrans ){ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " @@ -107,9 +98,27 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){ db->aDb[1].pBt = 0; sqlite3ResetInternalSchema(db, 0); } + return SQLITE_OK; +} +#endif /* SQLITE_PAGER_PRAGMAS */ + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +/* +** If the TEMP database is open, close it and mark the database schema +** as needing reloading. This must be done when using the TEMP_STORE +** or DEFAULT_TEMP_STORE pragmas. +*/ +static int changeTempStorage(Parse *pParse, const char *zStorageType){ + int ts = getTempStore(zStorageType); + sqlite3 *db = pParse->db; + if( db->temp_store==ts ) return SQLITE_OK; + if( invalidateTempStorage( pParse ) != SQLITE_OK ){ + return SQLITE_ERROR; + } db->temp_store = ts; return SQLITE_OK; } +#endif /* SQLITE_PAGER_PRAGMAS */ /* ** Generate code to return a single integer value. @@ -124,47 +133,56 @@ static void returnSingleInt(Parse *pParse, const char *zLabel, int value){ sqlite3VdbeAddOp(v, OP_Callback, 1, 0); } +#ifndef SQLITE_OMIT_FLAG_PRAGMAS /* ** Check to see if zRight and zLeft refer to a pragma that queries ** or changes one of the flags in db->flags. Return 1 if so and 0 if not. ** Also, implement the pragma. */ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ - static const struct { + static const struct sPragmaType { const char *zName; /* Name of the pragma */ int mask; /* Mask for the db->flags value */ } aPragma[] = { { "vdbe_trace", SQLITE_VdbeTrace }, { "sql_trace", SQLITE_SqlTrace }, { "vdbe_listing", SQLITE_VdbeListing }, -#if 1 /* FIX ME: Remove the following pragmas */ { "full_column_names", SQLITE_FullColNames }, { "short_column_names", SQLITE_ShortColNames }, { "count_changes", SQLITE_CountRows }, { "empty_result_callbacks", SQLITE_NullCallback }, -#endif + /* The following is VERY experimental */ + { "writable_schema", SQLITE_WriteSchema }, + { "omit_readlock", SQLITE_NoReadlock }, }; int i; - for(i=0; izName)==0 ){ sqlite3 *db = pParse->db; Vdbe *v; - if( zRight==0 ){ - v = sqlite3GetVdbe(pParse); - if( v ){ - returnSingleInt(pParse, - aPragma[i].zName, (db->flags&aPragma[i].mask)!=0); + v = sqlite3GetVdbe(pParse); + if( v ){ + if( zRight==0 ){ + returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); + }else{ + if( getBoolean(zRight) ){ + db->flags |= p->mask; + }else{ + db->flags &= ~p->mask; + } } - }else if( getBoolean(zRight) ){ - db->flags |= aPragma[i].mask; - }else{ - db->flags &= ~aPragma[i].mask; + /* If one of these pragmas is executed, any prepared statements + ** need to be recompiled. + */ + sqlite3VdbeAddOp(v, OP_Expire, 0, 0); } return 1; } } return 0; } +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ /* ** Process a pragma statement. @@ -217,6 +235,7 @@ void sqlite3Pragma( goto pragma_out; } +#ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N @@ -281,10 +300,31 @@ void sqlite3Pragma( int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0; returnSingleInt(pParse, "page_size", size); }else{ - sqlite3BtreeSetPageSize(pBt, atoi(zRight), sqlite3BtreeGetReserve(pBt)); + sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1); } }else +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ + /* + ** PRAGMA [database.]auto_vacuum + ** PRAGMA [database.]auto_vacuum=N + ** + ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. + */ +#ifndef SQLITE_OMIT_AUTOVACUUM + if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ + Btree *pBt = pDb->pBt; + if( !zRight ){ + int auto_vacuum = + pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM; + returnSingleInt(pParse, "auto_vacuum", auto_vacuum); + }else{ + sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight)); + } + }else +#endif + +#ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]cache_size ** PRAGMA [database.]cache_size=N @@ -330,6 +370,45 @@ void sqlite3Pragma( } }else + /* + ** PRAGMA temp_store_directory + ** PRAGMA temp_store_directory = ""|"directory_name" + ** + ** Return or set the local value of the temp_store_directory flag. Changing + ** the value sets a specific directory to be used for temporary files. + ** Setting to a null string reverts to the default temporary directory search. + ** If temporary directory is changed, then invalidateTempStorage. + ** + */ + if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ + if( !zRight ){ + if( sqlite3_temp_directory ){ + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, "temp_store_directory", P3_STATIC); + sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); + sqlite3VdbeAddOp(v, OP_Callback, 1, 0); + } + }else{ + if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){ + sqlite3ErrorMsg(pParse, "not a writable directory"); + goto pragma_out; + } + if( TEMP_STORE==0 + || (TEMP_STORE==1 && db->temp_store<=1) + || (TEMP_STORE==2 && db->temp_store==1) + ){ + invalidateTempStorage(pParse); + } + sqliteFree(sqlite3_temp_directory); + if( zRight[0] ){ + sqlite3_temp_directory = zRight; + zRight = 0; + }else{ + sqlite3_temp_directory = 0; + } + } + }else + /* ** PRAGMA [database.]synchronous ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL @@ -353,22 +432,16 @@ void sqlite3Pragma( } } }else +#endif /* SQLITE_OMIT_PAGER_PRAGMAS */ -#if 0 /* Used once during development. No longer needed */ - if( sqlite3StrICmp(zLeft, "trigger_overhead_test")==0 ){ - if( getBoolean(zRight) ){ - sqlite3_always_code_trigger_setup = 1; - }else{ - sqlite3_always_code_trigger_setup = 0; - } - }else -#endif - +#ifndef SQLITE_OMIT_FLAG_PRAGMAS if( flagPragma(pParse, zLeft, zRight) ){ /* The flagPragma() subroutine also generates any necessary code ** there is nothing more to do here */ }else +#endif /* SQLITE_OMIT_FLAG_PRAGMAS */ +#ifndef SQLITE_OMIT_SCHEMA_PRAGMAS /* ** PRAGMA table_info() ** @@ -401,8 +474,7 @@ void sqlite3Pragma( sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0); sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - pTab->aCol[i].zDflt, P3_STATIC); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt); sqlite3VdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0); sqlite3VdbeAddOp(v, OP_Callback, 6, 0); } @@ -458,6 +530,40 @@ void sqlite3Pragma( } }else + if( sqlite3StrICmp(zLeft, "database_list")==0 ){ + int i; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; + sqlite3VdbeSetNumCols(v, 3); + sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); + sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); + sqlite3VdbeSetColName(v, 2, "file", P3_STATIC); + for(i=0; inDb; i++){ + if( db->aDb[i].pBt==0 ) continue; + assert( db->aDb[i].zName!=0 ); + sqlite3VdbeAddOp(v, OP_Integer, i, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, + sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); + sqlite3VdbeAddOp(v, OP_Callback, 3, 0); + } + }else + + if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ + int i = 0; + HashElem *p; + sqlite3VdbeSetNumCols(v, 2); + sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); + sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); + for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ + CollSeq *pColl = (CollSeq *)sqliteHashData(p); + sqlite3VdbeAddOp(v, OP_Integer, i++, 0); + sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0); + sqlite3VdbeAddOp(v, OP_Callback, 2, 0); + } + }else +#endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ + +#ifndef SQLITE_OMIT_FOREIGN_KEY if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ FKey *pFK; Table *pTab; @@ -491,24 +597,7 @@ void sqlite3Pragma( } } }else - - if( sqlite3StrICmp(zLeft, "database_list")==0 ){ - int i; - if( sqlite3ReadSchema(pParse) ) goto pragma_out; - sqlite3VdbeSetNumCols(v, 3); - sqlite3VdbeSetColName(v, 0, "seq", P3_STATIC); - sqlite3VdbeSetColName(v, 1, "name", P3_STATIC); - sqlite3VdbeSetColName(v, 2, "file", P3_STATIC); - for(i=0; inDb; i++){ - if( db->aDb[i].pBt==0 ) continue; - assert( db->aDb[i].zName!=0 ); - sqlite3VdbeAddOp(v, OP_Integer, i, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); - sqlite3VdbeOp3(v, OP_String8, 0, 0, - sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); - sqlite3VdbeAddOp(v, OP_Callback, 3, 0); - } - }else +#endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ @@ -521,6 +610,7 @@ void sqlite3Pragma( }else #endif +#ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ int i, j, addr; @@ -645,6 +735,9 @@ void sqlite3Pragma( addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); sqlite3VdbeChangeP2(v, addr+2, addr+ArraySize(endCode)); }else +#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ + +#ifndef SQLITE_OMIT_UTF16 /* ** PRAGMA encoding ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" @@ -715,6 +808,69 @@ void sqlite3Pragma( } } }else +#endif /* SQLITE_OMIT_UTF16 */ + +#ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + /* + ** PRAGMA [database.]schema_version + ** PRAGMA [database.]schema_version = + ** + ** PRAGMA [database.]user_version + ** PRAGMA [database.]user_version = + ** + ** The pragma's schema_version and user_version are used to set or get + ** the value of the schema-version and user-version, respectively. Both + ** the schema-version and the user-version are 32-bit signed integers + ** stored in the database header. + ** + ** The schema-cookie is usually only manipulated internally by SQLite. It + ** is incremented by SQLite whenever the database schema is modified (by + ** creating or dropping a table or index). The schema version is used by + ** SQLite each time a query is executed to ensure that the internal cache + ** of the schema used when compiling the SQL query matches the schema of + ** the database against which the compiled query is actually executed. + ** Subverting this mechanism by using "PRAGMA schema_version" to modify + ** the schema-version is potentially dangerous and may lead to program + ** crashes or database corruption. Use with caution! + ** + ** The user-version is not used internally by SQLite. It may be used by + ** applications for any purpose. + */ + if( sqlite3StrICmp(zLeft, "schema_version")==0 || + sqlite3StrICmp(zLeft, "user_version")==0 ){ + + int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */ + if( zLeft[0]=='s' || zLeft[0]=='S' ){ + iCookie = 0; + }else{ + iCookie = 5; + } + + if( zRight ){ + /* Write the specified cookie value */ + static const VdbeOpList setCookie[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_Integer, 0, 0, 0}, /* 1 */ + { OP_SetCookie, 0, 0, 0}, /* 2 */ + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); + sqlite3VdbeChangeP1(v, addr+2, iDb); + sqlite3VdbeChangeP2(v, addr+2, iCookie); + }else{ + /* Read the specified cookie value */ + static const VdbeOpList readCookie[] = { + { OP_ReadCookie, 0, 0, 0}, /* 0 */ + { OP_Callback, 1, 0, 0} + }; + int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); + sqlite3VdbeChangeP1(v, addr, iDb); + sqlite3VdbeChangeP2(v, addr, iCookie); + sqlite3VdbeSetNumCols(v, 1); + } + } +#endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* @@ -748,7 +904,17 @@ void sqlite3Pragma( #endif {} + + if( v ){ + /* Code an OP_Expire at the end of each PRAGMA program to cause + ** the VDBE implementing the pragma to expire. Most (all?) pragmas + ** are only valid for a single execution. + */ + sqlite3VdbeAddOp(v, OP_Expire, 1, 0); + } pragma_out: sqliteFree(zLeft); sqliteFree(zRight); } + +#endif /* SQLITE_OMIT_PRAGMA */ diff --git a/db/sqlite3/src/printf.c b/db/sqlite3/src/printf.c index 43e12863721..6e700771b4b 100644 --- a/db/sqlite3/src/printf.c +++ b/db/sqlite3/src/printf.c @@ -99,6 +99,7 @@ typedef struct et_info { /* Information about each format field */ */ #define FLAG_SIGNED 1 /* True if the value to convert is signed */ #define FLAG_INTERN 2 /* True if for internal use only */ +#define FLAG_STRING 4 /* Allow infinity precision */ /* @@ -109,10 +110,10 @@ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; static const et_info fmtinfo[] = { { 'd', 10, 1, etRADIX, 0, 0 }, - { 's', 0, 0, etSTRING, 0, 0 }, - { 'z', 0, 2, etDYNSTRING, 0, 0 }, - { 'q', 0, 0, etSQLESCAPE, 0, 0 }, - { 'Q', 0, 0, etSQLESCAPE2, 0, 0 }, + { 's', 0, 4, etSTRING, 0, 0 }, + { 'z', 0, 6, etDYNSTRING, 0, 0 }, + { 'q', 0, 4, etSQLESCAPE, 0, 0 }, + { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, { 'o', 8, 0, etRADIX, 0, 2 }, { 'u', 10, 0, etRADIX, 0, 0 }, @@ -296,8 +297,6 @@ static int vxprintf( c = *++fmt; } } - /* Limit the precision to prevent overflowing buf[] during conversion */ - if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40; }else{ precision = -1; } @@ -328,6 +327,11 @@ static int vxprintf( } zExtra = 0; + /* Limit the precision to prevent overflowing buf[] during conversion */ + if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){ + precision = etBUFSIZE-40; + } + /* ** At this point, variables are initialized as follows: ** @@ -563,13 +567,15 @@ static int vxprintf( case etSQLESCAPE2: { int i, j, n, c, isnull; + int needQuote; char *arg = va_arg(ap,char*); isnull = arg==0; if( isnull ) arg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)"); for(i=n=0; (c=arg[i])!=0; i++){ if( c=='\'' ) n++; } - n += i + 1 + ((!isnull && xtype==etSQLESCAPE2) ? 2 : 0); + needQuote = !isnull && xtype==etSQLESCAPE2; + n += i + 1 + needQuote*2; if( n>etBUFSIZE ){ bufpt = zExtra = sqliteMalloc( n ); if( bufpt==0 ) return -1; @@ -577,12 +583,12 @@ static int vxprintf( bufpt = buf; } j = 0; - if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; + if( needQuote ) bufpt[j++] = '\''; for(i=0; (c=arg[i])!=0; i++){ bufpt[j++] = c; if( c=='\'' ) bufpt[j++] = c; } - if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; + if( needQuote ) bufpt[j++] = '\''; bufpt[j] = 0; length = j; if( precision>=0 && precisionpOrderBy = pOrderBy; pNew->isDistinct = isDistinct; pNew->op = TK_SELECT; - pNew->nLimit = nLimit; - pNew->nOffset = nOffset; + pNew->pLimit = pLimit; + pNew->pOffset = pOffset; pNew->iLimit = -1; pNew->iOffset = -1; } @@ -160,7 +163,9 @@ static void setToken(Token *p, const char *z){ static void addWhereTerm( const char *zCol, /* Name of the column */ const Table *pTab1, /* First table */ + const char *zAlias1, /* Alias for first table. May be NULL */ const Table *pTab2, /* Second table */ + const char *zAlias2, /* Alias for second table. May be NULL */ Expr **ppExpr /* Add the equality term to this expression */ ){ Token dummy; @@ -171,9 +176,15 @@ static void addWhereTerm( setToken(&dummy, zCol); pE1a = sqlite3Expr(TK_ID, 0, 0, &dummy); pE2a = sqlite3Expr(TK_ID, 0, 0, &dummy); - setToken(&dummy, pTab1->zName); + if( zAlias1==0 ){ + zAlias1 = pTab1->zName; + } + setToken(&dummy, zAlias1); pE1b = sqlite3Expr(TK_ID, 0, 0, &dummy); - setToken(&dummy, pTab2->zName); + if( zAlias2==0 ){ + zAlias2 = pTab2->zName; + } + setToken(&dummy, zAlias2); pE2b = sqlite3Expr(TK_ID, 0, 0, &dummy); pE1c = sqlite3Expr(TK_DOT, pE1b, pE1a, 0); pE2c = sqlite3Expr(TK_DOT, pE2b, pE2a, 0); @@ -241,7 +252,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ for(j=0; jnCol; j++){ char *zName = pLeftTab->aCol[j].zName; if( columnIndex(pRightTab, zName)>=0 ){ - addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere); + addWhereTerm(zName, pLeftTab, pLeft->zAlias, + pRightTab, pRight->zAlias, &p->pWhere); } } } @@ -279,7 +291,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ "not present in both tables", zName); return 1; } - addWhereTerm(zName, pLeftTab, pRightTab, &p->pWhere); + addWhereTerm(zName, pLeftTab, pLeft->zAlias, + pRightTab, pRight->zAlias, &p->pWhere); } } } @@ -298,20 +311,11 @@ void sqlite3SelectDelete(Select *p){ sqlite3ExprDelete(p->pHaving); sqlite3ExprListDelete(p->pOrderBy); sqlite3SelectDelete(p->pPrior); - sqliteFree(p->zSelect); + sqlite3ExprDelete(p->pLimit); + sqlite3ExprDelete(p->pOffset); sqliteFree(p); } -/* -** Delete the aggregate information from the parse structure. -*/ -static void sqliteAggregateInfoReset(Parse *pParse){ - sqliteFree(pParse->aAgg); - pParse->aAgg = 0; - pParse->nAgg = 0; - pParse->useAgg = 0; -} - /* ** Insert code into "v" that will push the record on the top of the ** stack into the sorter. @@ -336,9 +340,10 @@ static void codeLimiter( int nPop /* Number of times to pop stack when jumping */ ){ if( p->iOffset>=0 ){ - int addr = sqlite3VdbeCurrentAddr(v) + 2; + int addr = sqlite3VdbeCurrentAddr(v) + 3; if( nPop>0 ) addr++; - sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, addr); + sqlite3VdbeAddOp(v, OP_MemIncr, p->iOffset, 0); + sqlite3VdbeAddOp(v, OP_IfMemPos, p->iOffset, addr); if( nPop>0 ){ sqlite3VdbeAddOp(v, OP_Pop, nPop, 0); } @@ -425,6 +430,7 @@ static int selectInnerLoop( } switch( eDest ){ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* In this mode, write each query result to the key of the temporary ** table iParm. */ @@ -436,6 +442,20 @@ static int selectInnerLoop( break; } + /* Construct a record from the query result, but instead of + ** saving that record, use it as a key to delete elements from + ** the temporary table iParm. + */ + case SRT_Except: { + int addr; + addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); + sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); + sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3); + sqlite3VdbeAddOp(v, OP_Delete, iParm, 0); + break; + } +#endif + /* Store the result as data using a unique key. */ case SRT_Table: @@ -451,19 +471,7 @@ static int selectInnerLoop( break; } - /* Construct a record from the query result, but instead of - ** saving that record, use it as a key to delete elements from - ** the temporary table iParm. - */ - case SRT_Except: { - int addr; - addr = sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT); - sqlite3VdbeChangeP3(v, -1, aff, P3_STATIC); - sqlite3VdbeAddOp(v, OP_NotFound, iParm, addr+3); - sqlite3VdbeAddOp(v, OP_Delete, iParm, 0); - break; - } - +#ifndef SQLITE_OMIT_SUBQUERY /* If we are creating a set for an "expr IN (SELECT ...)" construct, ** then there should be a single item on the stack. Write this ** item into the set table with bogus data. @@ -493,6 +501,7 @@ static int selectInnerLoop( ** store the results in the appropriate memory cell and break out ** of the scan loop. */ + case SRT_Exists: case SRT_Mem: { assert( nColumn==1 ); if( pOrderBy ){ @@ -503,6 +512,7 @@ static int selectInnerLoop( } break; } +#endif /* #ifndef SQLITE_OMIT_SUBQUERY */ /* Send the data to the callback function. */ @@ -531,6 +541,7 @@ static int selectInnerLoop( break; } +#if !defined(SQLITE_OMIT_TRIGGER) /* Discard the results. This is used for SELECT statements inside ** the body of a TRIGGER. The purpose of such selects is to call ** user-defined functions that have side effects. We do not care @@ -541,6 +552,7 @@ static int selectInnerLoop( sqlite3VdbeAddOp(v, OP_Pop, nColumn, 0); break; } +#endif } return 0; } @@ -596,6 +608,7 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_PutIntKey, iParm, 0); break; } +#ifndef SQLITE_OMIT_SUBQUERY case SRT_Set: { assert( nColumn==1 ); sqlite3VdbeAddOp(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3); @@ -606,12 +619,14 @@ static void generateSortTail( sqlite3VdbeAddOp(v, OP_PutStrKey, (iParm&0x0000FFFF), 0); break; } + case SRT_Exists: case SRT_Mem: { assert( nColumn==1 ); sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); sqlite3VdbeAddOp(v, OP_Goto, 0, end1); break; } +#endif case SRT_Callback: case SRT_Subroutine: { int i; @@ -650,18 +665,31 @@ static void generateSortTail( ** The declaration type for an expression is either TEXT, NUMERIC or ANY. ** The declaration type for a ROWID field is INTEGER. */ -static const char *columnType(Parse *pParse, SrcList *pTabList, Expr *pExpr){ +static const char *columnType(NameContext *pNC, Expr *pExpr){ char const *zType; int j; - if( pExpr==0 || pTabList==0 ) return 0; + if( pExpr==0 || pNC->pSrcList==0 ) return 0; + + /* The TK_AS operator can only occur in ORDER BY, GROUP BY, HAVING, + ** and LIMIT clauses. But pExpr originates in the result set of a + ** SELECT. So pExpr can never contain an AS operator. + */ + assert( pExpr->op!=TK_AS ); switch( pExpr->op ){ case TK_COLUMN: { - Table *pTab; + Table *pTab = 0; int iCol = pExpr->iColumn; - for(j=0; jnSrc && pTabList->a[j].iCursor!=pExpr->iTable; j++){} - assert( jnSrc ); - pTab = pTabList->a[j].pTab; + while( pNC && !pTab ){ + SrcList *pTabList = pNC->pSrcList; + for(j=0;jnSrc && pTabList->a[j].iCursor!=pExpr->iTable;j++); + if( jnSrc ){ + pTab = pTabList->a[j].pTab; + }else{ + pNC = pNC->pNext; + } + } + assert( pTab ); if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); if( iCol<0 ){ @@ -671,14 +699,16 @@ static const char *columnType(Parse *pParse, SrcList *pTabList, Expr *pExpr){ } break; } - case TK_AS: - zType = columnType(pParse, pTabList, pExpr->pLeft); - break; +#ifndef SQLITE_OMIT_SUBQUERY case TK_SELECT: { + NameContext sNC; Select *pS = pExpr->pSelect; - zType = columnType(pParse, pS->pSrc, pS->pEList->a[0].pExpr); + sNC.pSrcList = pExpr->pSelect->pSrc; + sNC.pNext = pNC; + zType = columnType(&sNC, pS->pEList->a[0].pExpr); break; } +#endif default: zType = 0; } @@ -697,9 +727,11 @@ static void generateColumnTypes( ){ Vdbe *v = pParse->pVdbe; int i; + NameContext sNC; + sNC.pSrcList = pTabList; for(i=0; inExpr; i++){ Expr *p = pEList->a[i].pExpr; - const char *zType = columnType(pParse, pTabList, p); + const char *zType = columnType(&sNC, p); if( zType==0 ) continue; /* The vdbe must make it's own copy of the column-type, in case the ** schema is reset before this virtual machine is deleted. @@ -723,10 +755,12 @@ static void generateColumnNames( sqlite3 *db = pParse->db; int fullNames, shortNames; +#ifndef SQLITE_OMIT_EXPLAIN /* If this is an EXPLAIN, skip this step */ if( pParse->explain ){ return; } +#endif assert( v!=0 ); if( pParse->colNamesSet || v==0 || sqlite3_malloc_failed ) return; @@ -753,7 +787,7 @@ static void generateColumnNames( if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); if( iCol<0 ){ - zCol = "_ROWID_"; + zCol = "rowid"; }else{ zCol = pTab->aCol[iCol].zName; } @@ -768,7 +802,7 @@ static void generateColumnNames( sqlite3SetString(&zName, zTab, ".", zCol, 0); sqlite3VdbeSetColName(v, i, zName, P3_DYNAMIC); }else{ - sqlite3VdbeSetColName(v, i, zCol, 0); + sqlite3VdbeSetColName(v, i, zCol, strlen(zCol)); } }else if( p->span.z && p->span.z[0] ){ sqlite3VdbeSetColName(v, i, p->span.z, p->span.n); @@ -783,6 +817,7 @@ static void generateColumnNames( generateColumnTypes(pParse, pTabList, pEList); } +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Name of the connection operator, used for error messages. */ @@ -796,11 +831,12 @@ static const char *selectOpName(int id){ } return z; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ /* ** Forward declaration */ -static int fillInColumnList(Parse*, Select*); +static int prepSelectStmt(Parse*, Select*); /* ** Given a SELECT statement, generate a Table structure that describes @@ -812,7 +848,10 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ ExprList *pEList; Column *aCol, *pCol; - if( fillInColumnList(pParse, pSelect) ){ + if( prepSelectStmt(pParse, pSelect) ){ + return 0; + } + if( sqlite3SelectResolve(pParse, pSelect, 0) ){ return 0; } pTab = sqliteMalloc( sizeof(Table) ); @@ -825,38 +864,56 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ assert( pTab->nCol>0 ); pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol ); for(i=0, pCol=aCol; inCol; i++, pCol++){ - Expr *pR; + Expr *p, *pR; char *zType; char *zName; - Expr *p = pEList->a[i].pExpr; + char *zBasename; + int cnt; + NameContext sNC; + + /* Get an appropriate name for the column + */ + p = pEList->a[i].pExpr; assert( p->pRight==0 || p->pRight->token.z==0 || p->pRight->token.z[0]!=0 ); if( (zName = pEList->a[i].zName)!=0 ){ + /* If the column contains an "AS " phrase, use as the name */ zName = sqliteStrDup(zName); }else if( p->op==TK_DOT - && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ - int cnt; + && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){ + /* For columns of the from A.B use B as the name */ zName = sqlite3MPrintf("%T", &pR->token); - for(j=cnt=0; jtoken, ++cnt); - j = -1; - } - } }else if( p->span.z && p->span.z[0] ){ + /* Use the original text of the column expression as its name */ zName = sqlite3MPrintf("%T", &p->span); }else{ + /* If all else fails, make up a name */ zName = sqlite3MPrintf("column%d", i+1); } sqlite3Dequote(zName); + if( sqlite3_malloc_failed ) return 0; + + /* Make sure the column name is unique. If the name is not unique, + ** append a integer to the name so that it becomes unique. + */ + zBasename = zName; + for(j=cnt=0; jzName = zName; - zType = sqliteStrDup(columnType(pParse, pSelect->pSrc ,p)); + /* Get the typename, type affinity, and collating sequence for the + ** column. + */ + sNC.pSrcList = pSelect->pSrc; + zType = sqliteStrDup(columnType(&sNC, p)); pCol->zType = zType; - pCol->affinity = SQLITE_AFF_NUMERIC; - if( zType ){ - pCol->affinity = sqlite3AffinityType(zType, strlen(zType)); - } + pCol->affinity = sqlite3ExprAffinity(p); pCol->pColl = sqlite3ExprCollSeq(pParse, p); if( !pCol->pColl ){ pCol->pColl = pParse->db->pDfltColl; @@ -867,20 +924,24 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ } /* -** For the given SELECT statement, do three things. +** Prepare a SELECT statement for processing by doing the following +** things: ** -** (1) Fill in the pTabList->a[].pTab fields in the SrcList that -** defines the set of tables that should be scanned. For views, +** (1) Make sure VDBE cursor numbers have been assigned to every +** element of the FROM clause. +** +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** defines FROM clause. When views appear in the FROM clause, ** fill pTabList->a[].pSelect with a copy of the SELECT statement ** that implements the view. A copy is made of the view's SELECT ** statement so that we can freely modify or delete that statement ** without worrying about messing up the presistent representation ** of the view. ** -** (2) Add terms to the WHERE clause to accomodate the NATURAL keyword +** (3) Add terms to the WHERE clause to accomodate the NATURAL keyword ** on joins and the ON and USING clause of joins. ** -** (3) Scan the list of columns in the result set (pEList) looking +** (4) Scan the list of columns in the result set (pEList) looking ** for instances of the "*" operator or the TABLE.* operator. ** If found, expand each "*" to be every column in every table ** and TABLE.* to be every column in TABLE. @@ -888,25 +949,35 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){ ** Return 0 on success. If there are problems, leave an error message ** in pParse and return non-zero. */ -static int fillInColumnList(Parse *pParse, Select *p){ +static int prepSelectStmt(Parse *pParse, Select *p){ int i, j, k, rc; SrcList *pTabList; ExprList *pEList; Table *pTab; struct SrcList_item *pFrom; - if( p==0 || p->pSrc==0 ) return 1; + if( p==0 || p->pSrc==0 || sqlite3_malloc_failed ) return 1; pTabList = p->pSrc; pEList = p->pEList; - /* Look up every table in the table list. + /* Make sure cursor numbers have been assigned to all entries in + ** the FROM clause of the SELECT statement. + */ + sqlite3SrcListAssignCursors(pParse, p->pSrc); + + /* Look up every table named in the FROM clause of the select. If + ** an entry of the FROM clause is a subquery instead of a table or view, + ** then create a transient table structure to describe the subquery. */ for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - if( pFrom->pTab ){ - /* This routine has run before! No need to continue */ + if( pFrom->pTab!=0 ){ + /* This statement has already been prepared. There is no need + ** to go further. */ + assert( i==0 ); return 0; } if( pFrom->zName==0 ){ +#ifndef SQLITE_OMIT_SUBQUERY /* A sub-query in the FROM clause of a SELECT */ assert( pFrom->pSelect!=0 ); if( pFrom->zAlias==0 ){ @@ -923,6 +994,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ ** pTab is not pointing to a persistent table structure that defines ** part of the schema. */ pTab->isTransient = 1; +#endif }else{ /* An ordinary table or view name in the FROM clause */ pFrom->pTab = pTab = @@ -930,6 +1002,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ if( pTab==0 ){ return 1; } +#ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ /* We reach here if the named table is a really a view */ if( sqlite3ViewGetColumnNames(pParse, pTab) ){ @@ -944,6 +1017,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ pFrom->pSelect = sqlite3SelectDup(pTab->pSelect); } } +#endif } } @@ -1042,7 +1116,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ pExpr = pRight; pExpr->span = pExpr->token; } - pNew = sqlite3ExprListAppend(pNew, pExpr, 0); + pNew = sqlite3ExprListAppend(pNew, pExpr, &pRight->token); } } if( !tableSeen ){ @@ -1075,6 +1149,7 @@ static int fillInColumnList(Parse *pParse, Select *p){ ** will be left pointing to a deallocated Table structure after the ** DROP and a coredump will occur the next time the VIEW is used. */ +#if 0 void sqlite3SelectUnbind(Select *p){ int i; SrcList *pSrc = p->pSrc; @@ -1093,7 +1168,9 @@ void sqlite3SelectUnbind(Select *p){ } } } +#endif +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine associates entries in an ORDER BY expression list with ** columns in a result. For each ORDER BY expression, the opcode of @@ -1122,7 +1199,7 @@ static int matchOrderbyToColumn( if( mustComplete ){ for(i=0; inExpr; i++){ pOrderBy->a[i].done = 0; } } - if( fillInColumnList(pParse, pSelect) ){ + if( prepSelectStmt(pParse, pSelect) ){ return 1; } if( pSelect->pPrior ){ @@ -1165,6 +1242,7 @@ static int matchOrderbyToColumn( pE->op = TK_COLUMN; pE->iColumn = iCol; pE->iTable = iTable; + pE->iAgg = -1; pOrderBy->a[i].done = 1; } if( iCol<0 && mustComplete ){ @@ -1176,6 +1254,7 @@ static int matchOrderbyToColumn( } return nErr; } +#endif /* #ifndef SQLITE_OMIT_COMPOUND_SELECT */ /* ** Get a VDBE for the given parser context. Create a new one if necessary. @@ -1191,12 +1270,12 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ /* ** Compute the iLimit and iOffset fields of the SELECT based on the -** nLimit and nOffset fields. nLimit and nOffset hold the integers +** pLimit and pOffset expressions. nLimit and nOffset hold the expressions ** that appear in the original SQL statement after the LIMIT and OFFSET -** keywords. Or that hold -1 and 0 if those keywords are omitted. -** iLimit and iOffset are the integer memory register numbers for -** counters used to compute the limit and offset. If there is no -** limit and/or offset, then iLimit and iOffset are negative. +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then +** iLimit and iOffset are negative. ** ** This routine changes the values if iLimit and iOffset only if ** a limit or offset is defined by nLimit and nOffset. iLimit and @@ -1209,28 +1288,29 @@ Vdbe *sqlite3GetVdbe(Parse *pParse){ */ static void computeLimitRegisters(Parse *pParse, Select *p){ /* - ** If the comparison is p->nLimit>0 then "LIMIT 0" shows - ** all rows. It is the same as no limit. If the comparision is - ** p->nLimit>=0 then "LIMIT 0" show no rows at all. ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ - if( p->nLimit>=0 ){ + if( p->pLimit ){ int iMem = pParse->nMem++; Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3VdbeAddOp(v, OP_Integer, -p->nLimit, 0); + sqlite3ExprCode(pParse, p->pLimit); + sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); + sqlite3VdbeAddOp(v, OP_Negative, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1); VdbeComment((v, "# LIMIT counter")); p->iLimit = iMem; } - if( p->nOffset>0 ){ + if( p->pOffset ){ int iMem = pParse->nMem++; Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; - sqlite3VdbeAddOp(v, OP_Integer, -p->nOffset, 0); + sqlite3ExprCode(pParse, p->pOffset); + sqlite3VdbeAddOp(v, OP_MustBeInt, 0, 0); + sqlite3VdbeAddOp(v, OP_Negative, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iMem, 1); VdbeComment((v, "# OFFSET counter")); p->iOffset = iMem; @@ -1260,7 +1340,7 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ Vdbe *v = pParse->pVdbe; int addr; - if( fillInColumnList(pParse, p) ){ + if( prepSelectStmt(pParse, p) ){ return 0; } nColumn = p->pEList->nExpr; @@ -1282,6 +1362,7 @@ static int openTempIndex(Parse *pParse, Select *p, int iTab, int keyAsData){ return addr; } +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Add the address "addr" to the set of all OpenTemp opcode addresses ** that are being accumulated in p->ppOpenTemp. @@ -1294,7 +1375,9 @@ static int multiSelectOpenTempAddr(Select *p, int addr){ pList->a[pList->nId-1].idx = addr; return SQLITE_OK; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** Return the appropriate collating sequence for the iCol-th column of ** the result set for the compound-select statement "p". Return NULL if @@ -1315,7 +1398,9 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ } return pRet; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* ** This routine is called to process a query that is really the union ** or intersection of two or more separate queries. @@ -1375,7 +1460,7 @@ static int multiSelect( rc = 1; goto multi_select_end; } - if( pPrior->nLimit>=0 || pPrior->nOffset>0 ){ + if( pPrior->pLimit ){ sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", selectOpName(p->op)); rc = 1; @@ -1416,8 +1501,9 @@ static int multiSelect( switch( p->op ){ case TK_ALL: { if( p->pOrderBy==0 ){ - pPrior->nLimit = p->nLimit; - pPrior->nOffset = p->nOffset; + assert( !pPrior->pLimit ); + pPrior->pLimit = p->pLimit; + pPrior->pOffset = p->pOffset; rc = sqlite3Select(pParse, pPrior, eDest, iParm, 0, 0, 0, aff); if( rc ){ goto multi_select_end; @@ -1425,8 +1511,8 @@ static int multiSelect( p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; - p->nLimit = -1; - p->nOffset = 0; + p->pLimit = 0; + p->pOffset = 0; rc = sqlite3Select(pParse, p, eDest, iParm, 0, 0, 0, aff); p->pPrior = pPrior; if( rc ){ @@ -1441,12 +1527,12 @@ static int multiSelect( int unionTab; /* Cursor number of the temporary table holding result */ int op = 0; /* One of the SRT_ operations to apply to self */ int priorOp; /* The SRT_ operation to apply to prior selects */ - int nLimit, nOffset; /* Saved values of p->nLimit and p->nOffset */ - ExprList *pOrderBy; /* The ORDER BY clause for the right SELECT */ + Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ + ExprList *pOrderBy; /* The ORDER BY clause for the right SELECT */ int addr; priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union; - if( eDest==priorOp && p->pOrderBy==0 && p->nLimit<0 && p->nOffset==0 ){ + if( eDest==priorOp && p->pOrderBy==0 && !p->pLimit && !p->pOffset ){ /* We can reuse a temporary table generated by a SELECT to our ** right. */ @@ -1476,6 +1562,7 @@ static int multiSelect( /* Code the SELECT statements to our left */ + assert( !pPrior->pOrderBy ); rc = sqlite3Select(pParse, pPrior, priorOp, unionTab, 0, 0, 0, aff); if( rc ){ goto multi_select_end; @@ -1491,15 +1578,18 @@ static int multiSelect( p->pPrior = 0; pOrderBy = p->pOrderBy; p->pOrderBy = 0; - nLimit = p->nLimit; - p->nLimit = -1; - nOffset = p->nOffset; - p->nOffset = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; rc = sqlite3Select(pParse, p, op, unionTab, 0, 0, 0, aff); p->pPrior = pPrior; p->pOrderBy = pOrderBy; - p->nLimit = nLimit; - p->nOffset = nOffset; + sqlite3ExprDelete(p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; + p->iLimit = -1; + p->iOffset = -1; if( rc ){ goto multi_select_end; } @@ -1536,7 +1626,7 @@ static int multiSelect( case TK_INTERSECT: { int tab1, tab2; int iCont, iBreak, iStart; - int nLimit, nOffset; + Expr *pLimit, *pOffset; int addr; /* INTERSECT is different from the others since it requires @@ -1578,14 +1668,15 @@ static int multiSelect( assert( nAddrpPrior = 0; - nLimit = p->nLimit; - p->nLimit = -1; - nOffset = p->nOffset; - p->nOffset = 0; + pLimit = p->pLimit; + p->pLimit = 0; + pOffset = p->pOffset; + p->pOffset = 0; rc = sqlite3Select(pParse, p, SRT_Union, tab2, 0, 0, 0, aff); p->pPrior = pPrior; - p->nLimit = nLimit; - p->nOffset = nOffset; + sqlite3ExprDelete(p->pLimit); + p->pLimit = pLimit; + p->pOffset = pOffset; if( rc ){ goto multi_select_end; } @@ -1681,7 +1772,7 @@ static int multiSelect( Expr *pExpr = pOrderByTerm->pExpr; char *zName = pOrderByTerm->zName; assert( pExpr->op==TK_COLUMN && pExpr->iColumnpColl ); + /* assert( !pExpr->pColl ); */ if( zName ){ pExpr->pColl = sqlite3LocateCollSeq(pParse, zName, -1); }else{ @@ -1704,7 +1795,9 @@ multi_select_end: p->ppOpenTemp = 0; return rc; } +#endif /* SQLITE_OMIT_COMPOUND_SELECT */ +#ifndef SQLITE_OMIT_VIEW /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th @@ -1719,6 +1812,7 @@ multi_select_end: ** of the subquery rather the result set of the subquery. */ static void substExprList(ExprList*,int,ExprList*); /* Forward Decl */ +static void substSelect(Select *, int, ExprList *); /* Forward Decl */ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ if( pExpr==0 ) return; if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){ @@ -1742,22 +1836,34 @@ static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){ pExpr->iAgg = pNew->iAgg; sqlite3TokenCopy(&pExpr->token, &pNew->token); sqlite3TokenCopy(&pExpr->span, &pNew->span); + pExpr->pSelect = sqlite3SelectDup(pNew->pSelect); + pExpr->flags = pNew->flags; } }else{ substExpr(pExpr->pLeft, iTable, pEList); substExpr(pExpr->pRight, iTable, pEList); + substSelect(pExpr->pSelect, iTable, pEList); substExprList(pExpr->pList, iTable, pEList); } } -static void -substExprList(ExprList *pList, int iTable, ExprList *pEList){ +static void substExprList(ExprList *pList, int iTable, ExprList *pEList){ int i; if( pList==0 ) return; for(i=0; inExpr; i++){ substExpr(pList->a[i].pExpr, iTable, pEList); } } +static void substSelect(Select *p, int iTable, ExprList *pEList){ + if( !p ) return; + substExprList(p->pEList, iTable, pEList); + substExprList(p->pGroupBy, iTable, pEList); + substExprList(p->pOrderBy, iTable, pEList); + substExpr(p->pHaving, iTable, pEList); + substExpr(p->pWhere, iTable, pEList); +} +#endif /* !defined(SQLITE_OMIT_VIEW) */ +#ifndef SQLITE_OMIT_VIEW /* ** This routine attempts to flatten subqueries in order to speed ** execution. It returns 1 if it makes changes and 0 if no flattening @@ -1855,11 +1961,13 @@ static int flattenSubquery( if( subqueryIsAgg && pSrc->nSrc>1 ) return 0; pSubSrc = pSub->pSrc; assert( pSubSrc ); + if( (pSub->pLimit && p->pLimit) || pSub->pOffset || + (pSub->pLimit && isAgg) ) return 0; if( pSubSrc->nSrc==0 ) return 0; - if( (pSub->isDistinct || pSub->nLimit>=0) && (pSrc->nSrc>1 || isAgg) ){ + if( pSub->isDistinct && (pSrc->nSrc>1 || isAgg) ){ return 0; } - if( (p->isDistinct || p->nLimit>=0) && subqueryIsAgg ) return 0; + if( p->isDistinct && subqueryIsAgg ) return 0; if( p->pOrderBy && pSub->pOrderBy ) return 0; /* Restriction 3: If the subquery is a join, make sure the subquery is @@ -1991,17 +2099,13 @@ static int flattenSubquery( */ p->isDistinct = p->isDistinct || pSub->isDistinct; - /* Transfer the limit expression from the subquery to the outer - ** query. + /* + ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; */ - if( pSub->nLimit>=0 ){ - if( p->nLimit<0 ){ - p->nLimit = pSub->nLimit; - }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){ - p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset; - } + if( pSub->pLimit ){ + p->pLimit = pSub->pLimit; + pSub->pLimit = 0; } - p->nOffset += pSub->nOffset; /* Finially, delete what is left of the subquery and return ** success. @@ -2009,6 +2113,7 @@ static int flattenSubquery( sqlite3SelectDelete(pSub); return 1; } +#endif /* SQLITE_OMIT_VIEW */ /* ** Analyze the SELECT statement passed in as an argument to see if it @@ -2042,7 +2147,6 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ ExprList *pEList, *pList, eList; struct ExprList_item eListItem; SrcList *pSrc; - /* Check to see if this query is a simple min() or max() query. Return ** zero if it is not. @@ -2115,17 +2219,25 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ if( pIdx==0 ){ sqlite3VdbeAddOp(v, seekOp, base, 0); }else{ + /* Even though the cursor used to open the index here is closed + ** as soon as a single value has been read from it, allocate it + ** using (pParse->nTab++) to prevent the cursor id from being + ** reused. This is important for statements of the form + ** "INSERT INTO x SELECT max() FROM x". + */ + int iIdx; + iIdx = pParse->nTab++; sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0); - sqlite3VdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, + sqlite3VdbeOp3(v, OP_OpenRead, iIdx, pIdx->tnum, (char*)&pIdx->keyInfo, P3_KEYINFO); if( seekOp==OP_Rewind ){ sqlite3VdbeAddOp(v, OP_String, 0, 0); sqlite3VdbeAddOp(v, OP_MakeRecord, 1, 0); seekOp = OP_MoveGt; } - sqlite3VdbeAddOp(v, seekOp, base+1, 0); - sqlite3VdbeAddOp(v, OP_IdxRecno, base+1, 0); - sqlite3VdbeAddOp(v, OP_Close, base+1, 0); + sqlite3VdbeAddOp(v, seekOp, iIdx, 0); + sqlite3VdbeAddOp(v, OP_IdxRecno, iIdx, 0); + sqlite3VdbeAddOp(v, OP_Close, iIdx, 0); sqlite3VdbeAddOp(v, OP_MoveGe, base, 0); } eList.nExpr = 1; @@ -2148,41 +2260,193 @@ static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){ ** corresponding entry in the result set. */ static int processOrderGroupBy( - Parse *pParse, /* Parsing context */ + NameContext *pNC, /* Name context of the SELECT statement. */ ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ - SrcList *pTabList, /* The FROM clause */ - ExprList *pEList, /* The result set */ - int isAgg, /* True if aggregate functions are involved */ const char *zType /* Either "ORDER" or "GROUP", as appropriate */ ){ int i; + ExprList *pEList = pNC->pEList; /* The result set of the SELECT */ + Parse *pParse = pNC->pParse; /* The result set of the SELECT */ + assert( pEList ); + if( pOrderBy==0 ) return 0; for(i=0; inExpr; i++){ int iCol; Expr *pE = pOrderBy->a[i].pExpr; - if( sqlite3ExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){ - sqlite3ExprDelete(pE); - pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); - } - if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList, pE, isAgg, 0) ){ - return 1; - } - if( sqlite3ExprIsConstant(pE) ){ - if( sqlite3ExprIsInteger(pE, &iCol)==0 ){ - sqlite3ErrorMsg(pParse, - "%s BY terms must not be non-integer constants", zType); - return 1; - }else if( iCol<=0 || iCol>pEList->nExpr ){ + if( sqlite3ExprIsInteger(pE, &iCol) ){ + if( iCol>0 && iCol<=pEList->nExpr ){ + sqlite3ExprDelete(pE); + pE = pOrderBy->a[i].pExpr = sqlite3ExprDup(pEList->a[iCol-1].pExpr); + }else{ sqlite3ErrorMsg(pParse, "%s BY column number %d out of range - should be " "between 1 and %d", zType, iCol, pEList->nExpr); return 1; } } + if( sqlite3ExprResolveNames(pNC, pE) ){ + return 1; + } + if( sqlite3ExprIsConstant(pE) ){ + sqlite3ErrorMsg(pParse, + "%s BY terms must not be non-integer constants", zType); + return 1; + } } return 0; } +/* +** This routine resolves any names used in the result set of the +** supplied SELECT statement. If the SELECT statement being resolved +** is a sub-select, then pOuterNC is a pointer to the NameContext +** of the parent SELECT. +*/ +int sqlite3SelectResolve( + Parse *pParse, /* The parser context */ + Select *p, /* The SELECT statement being coded. */ + NameContext *pOuterNC /* The outer name context. May be NULL. */ +){ + ExprList *pEList; /* Result set. */ + int i; /* For-loop variable used in multiple places */ + NameContext sNC; /* Local name-context */ + + /* If this routine has run before, return immediately. */ + if( p->isResolved ){ + assert( !pOuterNC ); + return SQLITE_OK; + } + p->isResolved = 1; + + /* If there have already been errors, do nothing. */ + if( pParse->nErr>0 ){ + return SQLITE_ERROR; + } + + /* Prepare the select statement. This call will allocate all cursors + ** required to handle the tables and subqueries in the FROM clause. + */ + if( prepSelectStmt(pParse, p) ){ + return SQLITE_ERROR; + } + + /* Resolve the expressions in the LIMIT and OFFSET clauses. These + ** are not allowed to refer to any names, so pass an empty NameContext. + */ + sNC.pParse = pParse; + sNC.hasAgg = 0; + sNC.nErr = 0; + sNC.nRef = 0; + sNC.pEList = 0; + sNC.allowAgg = 0; + sNC.pSrcList = 0; + sNC.pNext = 0; + if( sqlite3ExprResolveNames(&sNC, p->pLimit) || + sqlite3ExprResolveNames(&sNC, p->pOffset) ){ + return SQLITE_ERROR; + } + + /* Set up the local name-context to pass to ExprResolveNames() to + ** resolve the expression-list. + */ + sNC.allowAgg = 1; + sNC.pSrcList = p->pSrc; + sNC.pNext = pOuterNC; + + /* NameContext.nDepth stores the depth of recursion for this query. For + ** an outer query (e.g. SELECT * FROM sqlite_master) this is 1. For + ** a subquery it is 2. For a subquery of a subquery, 3. And so on. + ** Parse.nMaxDepth is the maximum depth for any subquery resolved so + ** far. This is used to determine the number of aggregate contexts + ** required at runtime. + */ + sNC.nDepth = (pOuterNC?pOuterNC->nDepth+1:1); + if( sNC.nDepth>pParse->nMaxDepth ){ + pParse->nMaxDepth = sNC.nDepth; + } + + /* Resolve names in the result set. */ + pEList = p->pEList; + if( !pEList ) return SQLITE_ERROR; + for(i=0; inExpr; i++){ + Expr *pX = pEList->a[i].pExpr; + if( sqlite3ExprResolveNames(&sNC, pX) ){ + return SQLITE_ERROR; + } + } + + /* If there are no aggregate functions in the result-set, and no GROUP BY + ** expression, do not allow aggregates in any of the other expressions. + */ + assert( !p->isAgg ); + if( p->pGroupBy || sNC.hasAgg ){ + p->isAgg = 1; + }else{ + sNC.allowAgg = 0; + } + + /* If a HAVING clause is present, then there must be a GROUP BY clause. + */ + if( p->pHaving && !p->pGroupBy ){ + sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); + return SQLITE_ERROR; + } + + /* Add the expression list to the name-context before parsing the + ** other expressions in the SELECT statement. This is so that + ** expressions in the WHERE clause (etc.) can refer to expressions by + ** aliases in the result set. + ** + ** Minor point: If this is the case, then the expression will be + ** re-evaluated for each reference to it. + */ + sNC.pEList = p->pEList; + if( sqlite3ExprResolveNames(&sNC, p->pWhere) || + sqlite3ExprResolveNames(&sNC, p->pHaving) || + processOrderGroupBy(&sNC, p->pOrderBy, "ORDER") || + processOrderGroupBy(&sNC, p->pGroupBy, "GROUP") + ){ + return SQLITE_ERROR; + } + + return SQLITE_OK; +} + +/* +** An instance of the following struct is used by sqlite3Select() +** to save aggregate related information from the Parse object +** at the start of each call and to restore it at the end. See +** saveAggregateInfo() and restoreAggregateInfo(). +*/ +struct AggregateInfo { + int nAgg; + AggExpr *aAgg; +}; +typedef struct AggregateInfo AggregateInfo; + +/* +** Copy aggregate related information from the Parse structure +** into the AggregateInfo structure. Zero the aggregate related +** values in the Parse struct. +*/ +static void saveAggregateInfo(Parse *pParse, AggregateInfo *pInfo){ + pInfo->aAgg = pParse->aAgg; + pInfo->nAgg = pParse->nAgg; + pParse->aAgg = 0; + pParse->nAgg = 0; +} + +/* +** Copy aggregate related information from the AggregateInfo struct +** back into the Parse structure. The aggregate related information +** currently stored in the Parse structure is deleted. +*/ +static void restoreAggregateInfo(Parse *pParse, AggregateInfo *pInfo){ + sqliteFree(pParse->aAgg); + pParse->aAgg = pInfo->aAgg; + pParse->nAgg = pInfo->nAgg; +} + /* ** Generate code for the given SELECT statement. ** @@ -2248,7 +2512,7 @@ int sqlite3Select( int i; WhereInfo *pWInfo; Vdbe *v; - int isAgg = 0; /* True for select lists like "count(*)" */ + int isAgg; /* True for select lists like "count(*)" */ ExprList *pEList; /* List of columns to extract. */ SrcList *pTabList; /* List of tables to select from */ Expr *pWhere; /* The WHERE clause. May be NULL */ @@ -2258,28 +2522,39 @@ int sqlite3Select( int isDistinct; /* True if the DISTINCT keyword is present */ int distinct; /* Table to use for the distinct set */ int rc = 1; /* Value to return from this function */ + AggregateInfo sAggInfo; if( sqlite3_malloc_failed || pParse->nErr || p==0 ) return 1; if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; +#ifndef SQLITE_OMIT_COMPOUND_SELECT /* If there is are a sequence of queries, do the earlier ones first. */ if( p->pPrior ){ return multiSelect(pParse, p, eDest, iParm, aff); } +#endif + + saveAggregateInfo(pParse, &sAggInfo); + pOrderBy = p->pOrderBy; + if( eDest==SRT_Union || eDest==SRT_Except || eDest==SRT_Discard ){ + p->pOrderBy = 0; + } + if( sqlite3SelectResolve(pParse, p, 0) ){ + goto select_end; + } + p->pOrderBy = pOrderBy; /* Make local copies of the parameters for this query. */ pTabList = p->pSrc; pWhere = p->pWhere; - pOrderBy = p->pOrderBy; pGroupBy = p->pGroupBy; pHaving = p->pHaving; + isAgg = p->isAgg; isDistinct = p->isDistinct; - - /* Allocate VDBE cursors for each table in the FROM clause - */ - sqlite3SrcListAssignCursors(pParse, pTabList); + pEList = p->pEList; + if( pEList==0 ) goto select_end; /* ** Do not even attempt to generate any code if we have already seen @@ -2287,25 +2562,17 @@ int sqlite3Select( */ if( pParse->nErr>0 ) goto select_end; - /* Expand any "*" terms in the result set. (For example the "*" in - ** "SELECT * FROM t1") The fillInColumnlist() routine also does some - ** other housekeeping - see the header comment for details. - */ - if( fillInColumnList(pParse, p) ){ - goto select_end; - } - pWhere = p->pWhere; - pEList = p->pEList; - if( pEList==0 ) goto select_end; - /* If writing to memory or generating a set ** only a single column may be output. */ + assert( eDest!=SRT_Exists || pEList->nExpr==1 ); +#ifndef SQLITE_OMIT_SUBQUERY if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){ sqlite3ErrorMsg(pParse, "only a single result allowed for " "a SELECT that is part of an expression"); goto select_end; } +#endif /* ORDER BY is ignored for some destinations. */ @@ -2319,35 +2586,6 @@ int sqlite3Select( break; } - /* At this point, we should have allocated all the cursors that we - ** need to handle subquerys and temporary tables. - ** - ** Resolve the column names and do a semantics check on all the expressions. - */ - for(i=0; inExpr; i++){ - if( sqlite3ExprResolveAndCheck(pParse, pTabList, 0, pEList->a[i].pExpr, - 1, &isAgg) ){ - goto select_end; - } - } - if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList, pWhere, 0, 0) ){ - goto select_end; - } - if( pHaving ){ - if( pGroupBy==0 ){ - sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); - goto select_end; - } - if( sqlite3ExprResolveAndCheck(pParse, pTabList, pEList,pHaving,1,&isAgg) ){ - goto select_end; - } - } - if( processOrderGroupBy(pParse, pOrderBy, pTabList, pEList, isAgg, "ORDER") - || processOrderGroupBy(pParse, pGroupBy, pTabList, pEList, isAgg, "GROUP") - ){ - goto select_end; - } - /* Begin generating code. */ v = sqlite3GetVdbe(pParse); @@ -2362,6 +2600,7 @@ int sqlite3Select( /* Generate code for all sub-queries in the FROM clause */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; inSrc; i++){ const char *zSavedAuthContext = 0; int needRestoreContext; @@ -2388,6 +2627,7 @@ int sqlite3Select( pHaving = p->pHaving; isDistinct = p->isDistinct; } +#endif /* Check for the special case of a min() or max() function by itself ** in the result set. @@ -2400,11 +2640,13 @@ int sqlite3Select( /* Check to see if this is a subquery that can be "flattened" into its parent. ** If flattening is a possiblity, do so and return immediately. */ +#ifndef SQLITE_OMIT_VIEW if( pParent && pParentAgg && flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){ if( isAgg ) *pParentAgg = 1; - return rc; + goto select_end; } +#endif /* If there is an ORDER BY clause, resolve any collation sequences ** names that have been explicitly specified. @@ -2434,28 +2676,32 @@ int sqlite3Select( /* Do an analysis of aggregate expressions. */ - sqliteAggregateInfoReset(pParse); if( isAgg || pGroupBy ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pParse; + sNC.pSrcList = pTabList; + assert( pParse->nAgg==0 ); isAgg = 1; for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(pParse, pEList->a[i].pExpr) ){ + if( sqlite3ExprAnalyzeAggregates(&sNC, pEList->a[i].pExpr) ){ goto select_end; } } if( pGroupBy ){ for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(pParse, pGroupBy->a[i].pExpr) ){ + if( sqlite3ExprAnalyzeAggregates(&sNC, pGroupBy->a[i].pExpr) ){ goto select_end; } } } - if( pHaving && sqlite3ExprAnalyzeAggregates(pParse, pHaving) ){ + if( pHaving && sqlite3ExprAnalyzeAggregates(&sNC, pHaving) ){ goto select_end; } if( pOrderBy ){ for(i=0; inExpr; i++){ - if( sqlite3ExprAnalyzeAggregates(pParse, pOrderBy->a[i].pExpr) ){ + if( sqlite3ExprAnalyzeAggregates(&sNC, pOrderBy->a[i].pExpr) ){ goto select_end; } } @@ -2490,10 +2736,10 @@ int sqlite3Select( } } - /* Initialize the memory cell to NULL + /* Initialize the memory cell to NULL for SRT_Mem or 0 for SRT_Exists */ - if( eDest==SRT_Mem ){ - sqlite3VdbeAddOp(v, OP_String8, 0, 0); + if( eDest==SRT_Mem || eDest==SRT_Exists ){ + sqlite3VdbeAddOp(v, eDest==SRT_Mem ? OP_String8 : OP_Integer, 0, 0); sqlite3VdbeAddOp(v, OP_MemStore, iParm, 1); } @@ -2508,8 +2754,8 @@ int sqlite3Select( /* Begin the database scan */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, - pGroupBy ? 0 : &pOrderBy); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, + pGroupBy ? 0 : &pOrderBy, p->pFetch); if( pWInfo==0 ) goto select_end; /* Use the standard inner loop if we are not dealing with @@ -2527,8 +2773,9 @@ int sqlite3Select( */ else{ AggExpr *pAgg; + int lbl1 = 0; + pParse->fillAgg = 1; if( pGroupBy ){ - int lbl1; for(i=0; inExpr; i++){ sqlite3ExprCode(pParse, pGroupBy->a[i].pExpr); } @@ -2537,11 +2784,14 @@ int sqlite3Select( sqlite3VdbeAddOp(v, OP_MakeRecord, pGroupBy->nExpr, 0); lbl1 = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp(v, OP_AggFocus, 0, lbl1); - for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ - if( pAgg->isAgg ) continue; - sqlite3ExprCode(pParse, pAgg->pExpr); - sqlite3VdbeAddOp(v, OP_AggSet, 0, i); - } + } + for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ + if( pAgg->isAgg ) continue; + sqlite3ExprCode(pParse, pAgg->pExpr); + sqlite3VdbeAddOp(v, OP_AggSet, 0, i); + } + pParse->fillAgg = 0; + if( lbl1<0 ){ sqlite3VdbeResolveLabel(v, lbl1); } for(i=0, pAgg=pParse->aAgg; inAgg; i++, pAgg++){ @@ -2581,7 +2831,6 @@ int sqlite3Select( int endagg = sqlite3VdbeMakeLabel(v); int startagg; startagg = sqlite3VdbeAddOp(v, OP_AggNext, 0, endagg); - pParse->useAgg = 1; if( pHaving ){ sqlite3ExprIfFalse(pParse, pHaving, startagg, 1); } @@ -2592,7 +2841,6 @@ int sqlite3Select( sqlite3VdbeAddOp(v, OP_Goto, 0, startagg); sqlite3VdbeResolveLabel(v, endagg); sqlite3VdbeAddOp(v, OP_Noop, 0, 0); - pParse->useAgg = 0; } /* If there is an ORDER BY clause, then we need to sort the results @@ -2602,6 +2850,7 @@ int sqlite3Select( generateSortTail(pParse, p, v, pEList->nExpr, eDest, iParm); } +#ifndef SQLITE_OMIT_SUBQUERY /* If this was a subquery, we have now converted the subquery into a ** temporary table. So delete the subquery structure from the parent ** to prevent this subquery from being evaluated again and to force the @@ -2613,6 +2862,7 @@ int sqlite3Select( sqlite3SelectDelete(p); pParent->pSrc->a[parentTab].pSelect = 0; } +#endif /* The SELECT was successfully coded. Set the return code to 0 ** to indicate no errors. @@ -2623,6 +2873,6 @@ int sqlite3Select( ** successful coding of the SELECT. */ select_end: - sqliteAggregateInfoReset(pParse); + restoreAggregateInfo(pParse, &sAggInfo); return rc; } diff --git a/db/sqlite3/src/shell.c b/db/sqlite3/src/shell.c index f9bb0b25c9e..aa92f3ff721 100644 --- a/db/sqlite3/src/shell.c +++ b/db/sqlite3/src/shell.c @@ -12,7 +12,7 @@ ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. ** -** $Id: shell.c,v 1.116 2004/10/07 00:32:40 drh Exp $ +** $Id: shell.c,v 1.122 2005/02/23 12:35:41 drh Exp $ */ #include #include @@ -196,7 +196,9 @@ static char *one_input_line(const char *zPrior, FILE *in){ zPrompt = mainPrompt; } zResult = readline(zPrompt); +#if defined(HAVE_READLINE) && HAVE_READLINE==1 if( zResult ) add_history(zResult); +#endif return zResult; } @@ -360,6 +362,7 @@ static void output_csv(struct callback_data *p, const char *z, int bSep){ } } +#ifdef SIGINT /* ** This routine runs when the user presses Ctrl-C */ @@ -367,6 +370,7 @@ static void interrupt_handler(int NotUsed){ seenInterrupt = 1; if( db ) sqlite3_interrupt(db); } +#endif /* ** This is the callback routine that the SQLite library @@ -652,7 +656,11 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){ zType = azArg[1]; zSql = azArg[2]; - fprintf(p->out, "%s;\n", zSql); + if( strcmp(zTable,"sqlite_sequence")!=0 ){ + fprintf(p->out, "%s;\n", zSql); + }else{ + fprintf(p->out, "DELETE FROM sqlite_sequence;\n"); + } if( strcmp(zType, "table")==0 ){ sqlite3_stmt *pTableInfo = 0; @@ -746,7 +754,7 @@ static char zHelp[] = ".help Show this message\n" ".import FILE TABLE Import data from FILE into TABLE\n" ".indices TABLE Show names of all indices on TABLE\n" - ".mode MODE ?TABLE? Set output mode where MODE is on of:\n" + ".mode MODE ?TABLE? Set output mode where MODE is one of:\n" " csv Comma-separated values\n" " column Left-aligned columns. (See .width)\n" " html HTML
code\n" @@ -882,6 +890,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){ data.colWidth[0] = 3; data.colWidth[1] = 15; data.colWidth[2] = 58; + data.cnt = 0; sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); @@ -1677,7 +1686,11 @@ int main(int argc, char **argv){ if( i", where +** X is the major version number, Y is the minor version number and Z +** is the release number. The trailing string is often "alpha" or "beta". +** For example "3.1.1beta". +** +** The SQLITE_VERSION_NUMBER is an integer with the value +** (X*100000 + Y*1000 + Z). For example, for version "3.1.1beta", +** SQLITE_VERSION_NUMBER is set to 3001001. To detect if they are using +** version 3.1.1 or greater at compile time, programs may use the test +** (SQLITE_VERSION_NUMBER>=3001001). +*/ +#ifdef SQLITE_VERSION_NUMBER +# undef SQLITE_VERSION_NUMBER +#endif +#define SQLITE_VERSION_NUMBER 3002000 /* ** The version string is also compiled into the library so that a program @@ -44,6 +60,12 @@ extern "C" { extern const char sqlite3_version[]; const char *sqlite3_libversion(void); +/* +** Return the value of the SQLITE_VERSION_NUMBER macro when the +** library was compiled. +*/ +int sqlite3_libversion_number(void); + /* ** Each open sqlite database is represented by an instance of the ** following opaque structure. @@ -309,7 +331,7 @@ int sqlite3_busy_timeout(sqlite3*, int ms); ** pass the result data pointer to sqlite3_free_table() in order to ** release the memory that was malloc-ed. Because of the way the ** malloc() happens, the calling function must not try to call -** malloc() directly. Only sqlite3_free_table() is able to release +** free() directly. Only sqlite3_free_table() is able to release ** the memory properly and safely. ** ** The return value of this routine is the same as from sqlite3_exec(). @@ -428,6 +450,8 @@ int sqlite3_set_authorizer( #define SQLITE_UPDATE 23 /* Table Name Column Name */ #define SQLITE_ATTACH 24 /* Filename NULL */ #define SQLITE_DETACH 25 /* Database Name NULL */ +#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ +#define SQLITE_REINDEX 27 /* Index Name NULL */ /* @@ -448,8 +472,8 @@ void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); /* ** This routine configures a callback function - the progress callback - that ** is invoked periodically during long running calls to sqlite3_exec(), -** sqlite3_step() and sqlite3_get_table(). An example use for this API is to keep -** a GUI updated during a large query. +** sqlite3_step() and sqlite3_get_table(). An example use for this API is to +** keep a GUI updated during a large query. ** ** The progress callback is invoked once for every N virtual machine opcodes, ** where N is the second argument to this function. The progress callback @@ -606,14 +630,19 @@ typedef struct Mem sqlite3_value; /* ** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(), -** one or more literals can be replace by a wildcard "?" or ":N:" where -** N is an integer. These value of these wildcard literals can be set -** using the routines listed below. +** one or more literals can be replace by parameters "?" or ":AAA" or +** "$VVV" where AAA is an identifer and VVV is a variable name according +** to the syntax rules of the TCL programming language. +** The value of these parameters (also called "host parameter names") can +** be set using the routines listed below. ** ** In every case, the first parameter is a pointer to the sqlite3_stmt ** structure returned from sqlite3_prepare(). The second parameter is the -** index of the wildcard. The first "?" has an index of 1. ":N:" wildcards -** use the index N. +** index of the parameter. The first parameter as an index of 1. For +** named parameters (":AAA" or "$VVV") you can use +** sqlite3_bind_parameter_index() to get the correct index value given +** the parameters name. If the same named parameter occurs more than +** once, it is assigned the same index each time. ** ** The fifth parameter to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or @@ -624,8 +653,8 @@ typedef struct Mem sqlite3_value; ** own private copy of the data. ** ** The sqlite3_bind_* routine must be called before sqlite3_step() after -** an sqlite3_prepare() or sqlite3_reset(). Unbound wildcards are interpreted -** as NULL. +** an sqlite3_prepare() or sqlite3_reset(). Unbound parameterss are +** interpreted as NULL. */ int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); int sqlite3_bind_double(sqlite3_stmt*, int, double); @@ -637,16 +666,16 @@ int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); /* -** Return the number of wildcards in a compiled SQL statement. This +** Return the number of parameters in a compiled SQL statement. This ** routine was added to support DBD::SQLite. */ int sqlite3_bind_parameter_count(sqlite3_stmt*); /* -** Return the name of the i-th parameter. Ordinary wildcards "?" are -** nameless and a NULL is returned. For wildcards of the form :N or -** $vvvv the complete text of the wildcard is returned. -** NULL is returned if the index is out of range. +** Return the name of the i-th parameter. Ordinary parameters "?" are +** nameless and a NULL is returned. For parameters of the form :AAA or +** $VVV the complete text of the parameter name is returned, including +** the initial ":" or "$". NULL is returned if the index is out of range. */ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); @@ -657,6 +686,13 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); */ int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); +/* +** Set all the parameters in the compiled SQL statement to NULL. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_clear_bindings(sqlite3_stmt*); + /* ** Return the number of columns in the result set returned by the compiled ** SQL statement. This routine returns 0 if pStmt is an SQL statement @@ -1148,17 +1184,62 @@ int sqlite3_rekey( ); /* -** If the following global variable is made to point to a constant +** Sleep for a little while. The second parameter is the number of +** miliseconds to sleep for. +** +** If the operating system does not support sleep requests with +** milisecond time resolution, then the time will be rounded up to +** the nearest second. The number of miliseconds of sleep actually +** requested from the operating system is returned. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_sleep(int); + +/* +** Return TRUE (non-zero) of the statement supplied as an argument needs +** to be recompiled. A statement needs to be recompiled whenever the +** execution environment changes in a way that would alter the program +** that sqlite3_prepare() generates. For example, if new functions or +** collating sequences are registered or if an authorizer function is +** added or changed. +** +******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** +*/ +int sqlite3_expired(sqlite3_stmt*); + +/* +** If the following global variable is made to point to a ** string which is the name of a directory, then all temporary files ** created by SQLite will be placed in that directory. If this variable ** is NULL pointer, then SQLite does a search for an appropriate temporary ** file directory. ** -** This variable should only be changed when there are no open databases. -** Once sqlite3_open() has been called, this variable should not be changed -** until all database connections are closed. +** Once sqlite3_open() has been called, changing this variable will invalidate +** the current temporary database, if any. */ -extern const char *sqlite3_temp_directory; +extern char *sqlite3_temp_directory; + +/* +** This function is called to recover from a malloc() failure that occured +** within the SQLite library. Normally, after a single malloc() fails the +** library refuses to function (all major calls return SQLITE_NOMEM). +** This function library state so that it can be used again. +** +** All existing statements (sqlite3_stmt pointers) must be finalized or +** reset before this call is made. Otherwise, SQLITE_BUSY is returned. +** If any in-memory databases are in use, either as a main or TEMP +** database, SQLITE_ERROR is returned. In either of these cases, the +** library is not reset and remains unusable. +** +** This function is *not* threadsafe. Calling this from within a threaded +** application when threads other than the caller have used SQLite is +** dangerous and will almost certainly result in malfunctions. +** +** This functionality can be omitted from a build by defining the +** SQLITE_OMIT_GLOBALRECOVER at compile time. +*/ +int sqlite3_global_recover(); #ifdef __cplusplus } /* End of the 'extern "C"' block */ diff --git a/db/sqlite3/src/sqliteInt.h b/db/sqlite3/src/sqliteInt.h index 9b712ba4446..3934a6b6317 100644 --- a/db/sqlite3/src/sqliteInt.h +++ b/db/sqlite3/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.327 2004/10/05 02:41:43 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.374 2005/03/21 04:04:03 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -47,13 +47,25 @@ #include #include #include +#include /* ** The maximum number of in-memory pages to use for the main database -** table and for temporary tables. +** table and for temporary tables. Internally, the MAX_PAGES and +** TEMP_PAGES macros are used. To override the default values at +** compilation time, the SQLITE_DEFAULT_CACHE_SIZE and +** SQLITE_DEFAULT_TEMP_CACHE_SIZE macros should be set. */ -#define MAX_PAGES 2000 -#define TEMP_PAGES 500 +#ifdef SQLITE_DEFAULT_CACHE_SIZE +# define MAX_PAGES SQLITE_DEFAULT_CACHE_SIZE +#else +# define MAX_PAGES 2000 +#endif +#ifdef SQLITE_DEFAULT_TEMP_CACHE_SIZE +# define TEMP_PAGES SQLITE_DEFAULT_TEMP_CACHE_SIZE +#else +# define TEMP_PAGES 500 +#endif /* ** If the following macro is set to 1, then NULL values are considered @@ -102,10 +114,28 @@ ** a minimum. */ /* #define SQLITE_OMIT_AUTHORIZATION 1 */ -/* #define SQLITE_OMIT_INMEMORYDB 1 */ +/* #define SQLITE_OMIT_MEMORYDB 1 */ /* #define SQLITE_OMIT_VACUUM 1 */ /* #define SQLITE_OMIT_DATETIME_FUNCS 1 */ /* #define SQLITE_OMIT_PROGRESS_CALLBACK 1 */ +/* #define SQLITE_OMIT_AUTOVACUUM */ +/* #define SQLITE_OMIT_ALTERTABLE */ + +/* +** Provide a default value for TEMP_STORE in case it is not specified +** on the command-line +*/ +#ifndef TEMP_STORE +# define TEMP_STORE 1 +#endif + +/* +** GCC does not define the offsetof() macro so we'll have to do it +** ourselves. +*/ +#ifndef offsetof +#define offsetof(STRUCTURE,FIELD) ((int)((char*)&((STRUCTURE*)0)->FIELD)) +#endif /* ** Integers of known sizes. These typedefs might change for architectures @@ -213,7 +243,7 @@ struct BusyHandler { ** each malloc() and free(). This output can be analyzed ** by an AWK script to determine if there are any leaks. */ -#ifdef SQLITE_DEBUG +#ifdef SQLITE_MEMDEBUG # define sqliteMalloc(X) sqlite3Malloc_(X,1,__FILE__,__LINE__) # define sqliteMallocRaw(X) sqlite3Malloc_(X,0,__FILE__,__LINE__) # define sqliteFree(X) sqlite3Free_(X,__FILE__,__LINE__) @@ -239,10 +269,11 @@ extern int sqlite3_malloc_failed; ** The following global variables are used for testing and debugging ** only. They only work if SQLITE_DEBUG is defined. */ -#ifdef SQLITE_DEBUG -extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ -extern int sqlite3_nFree; /* Number of sqliteFree() calls */ -extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ +#ifdef SQLITE_MEMDEBUG +extern int sqlite3_nMalloc; /* Number of sqliteMalloc() calls */ +extern int sqlite3_nFree; /* Number of sqliteFree() calls */ +extern int sqlite3_iMallocFail; /* Fail sqliteMalloc() after this many calls */ +extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */ #endif /* @@ -296,6 +327,8 @@ typedef struct AuthContext AuthContext; typedef struct KeyClass KeyClass; typedef struct CollSeq CollSeq; typedef struct KeyInfo KeyInfo; +typedef struct NameContext NameContext; +typedef struct Fetch Fetch; /* ** Each database file to be accessed by the system is an instance @@ -316,7 +349,8 @@ struct Db { u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u8 safety_level; /* How aggressive at synching data to disk */ int cache_size; /* Number of pages to use in the cache */ - void *pAux; /* Auxiliary data. Usually NULL */ + Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ + void *pAux; /* Auxiliary data. Usually NULL */ void (*xFreeAux)(void*); /* Routine to free pAux */ }; @@ -408,7 +442,6 @@ struct sqlite3 { void *pProgressArg; /* Argument to the progress callback */ int nProgressOps; /* Number of opcodes for progress callback */ #endif - int errCode; /* Most recent error code (SQLITE_*) */ u8 enc; /* Text encoding for this database. */ u8 autoCommit; /* The auto-commit flag. */ @@ -417,9 +450,11 @@ struct sqlite3 { void *pCollNeededArg; sqlite3_value *pValue; /* Value used for transient conversions */ sqlite3_value *pErr; /* Most recent error message */ - char *zErrMsg; /* Most recent error message (UTF-8 encoded) */ - char *zErrMsg16; /* Most recent error message (UTF-8 encoded) */ + char *zErrMsg16; /* Most recent error message (UTF-16 encoded) */ +#ifndef SQLITE_OMIT_GLOBALRECOVER + sqlite3 *pNext; /* Linked list of open db handles. */ +#endif }; /* @@ -443,6 +478,9 @@ struct sqlite3 { /* result set is empty */ #define SQLITE_SqlTrace 0x00000200 /* Debug print SQL as it executes */ #define SQLITE_VdbeListing 0x00000400 /* Debug listings of VDBE programs */ +#define SQLITE_WriteSchema 0x00000800 /* OK to update SQLITE_MASTER */ +#define SQLITE_NoReadlock 0x00001000 /* Readlocks are omitted when + ** accessing read-only databases */ /* ** Possible values for the sqlite.magic field. @@ -478,7 +516,7 @@ struct FuncDef { */ struct Column { char *zName; /* Name of this column */ - char *zDflt; /* Default value of this column */ + Expr *pDflt; /* Default value of this column */ char *zType; /* Data type for this column */ CollSeq *pColl; /* Collating sequence. If NULL, use the default */ u8 notNull; /* True if there is a NOT NULL constraint */ @@ -572,9 +610,13 @@ struct Table { u8 isTransient; /* True if automatically deleted when VDBE finishes */ u8 hasPrimKey; /* True if there exists a primary key */ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ + u8 autoInc; /* True if the integer primary key is autoincrement */ Trigger *pTrigger; /* List of SQL triggers on this table */ FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ +#ifndef SQLITE_OMIT_ALTERTABLE + int addColOffset; /* Offset in CREATE TABLE statement to add a new column */ +#endif }; /* @@ -759,10 +801,20 @@ struct Token { ** marker (a question mark character '?' in the original SQL) then the ** Expr.iTable holds the index number for that variable. ** +** If the expression is a subquery then Expr.iColumn holds an integer +** register number containing the result of the subquery. If the +** subquery gives a constant result, then iTable is -1. If the subquery +** gives a different answer at different times during statement processing +** then iTable is the address of a subroutine that computes the subquery. +** ** The Expr.pSelect field points to a SELECT statement. The SELECT might ** be the right operand of an IN operator. Or, if a scalar SELECT appears ** in an expression the opcode is TK_SELECT and Expr.pSelect is the only ** operand. +** +** If the Expr is of type OP_Column, and the table it is selecting from +** is a disk table or the "old.*" pseudo-table, then pTab points to the +** corresponding table definition. */ struct Expr { u8 op; /* Operation performed by this node */ @@ -777,16 +829,23 @@ struct Expr { Token span; /* Complete text of the expression */ int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the ** iColumn-th field of the iTable-th table. */ - int iAgg; /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull + int iAgg; /* When op==TK_COLUMN and pParse->fillAgg==FALSE, pull ** result from the iAgg-th element of the aggregator */ + int iAggCtx; /* The value to pass as P1 of OP_AggGet. */ Select *pSelect; /* When the expression is a sub-select. Also the ** right side of " IN (