#
#
# patch "ChangeLog"
# from [3cb7bfb9055fc1669cb3bce2a8b6494d9a4b6107]
# to [65ed20b61dbbcf7cb783764fddde4c8490b34952]
#
# patch "sqlite/alter.c"
# from [eba661e77bfd00282fbfa316cdb6aef04856fedc]
# to [2c79ec40f65e33deaf90ca493422c74586e481a3]
#
# patch "sqlite/btree.c"
# from [c4757940df58fc0914d2c4f1778a66101df2c6b9]
# to [e7d1694ad0844918e20b802a249533789bf811dc]
#
# patch "sqlite/build.c"
# from [2ea8ad0e2e49b3957692588182524e6c390ab5a9]
# to [02aedde724dc73295d6e9b8dc29afb5dd38de507]
#
# patch "sqlite/date.c"
# from [cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e]
# to [9602457c49210f77f860d1919a8249a3118cd43f]
#
# patch "sqlite/expr.c"
# from [715734d8681c5ad179a24156800b5c5646489e05]
# to [3d2cf15fd9aa6b60b67f45504782cce72cd07963]
#
# patch "sqlite/func.c"
# from [f357a81bcdd83684cb198a8ad96be1c21e29f85c]
# to [af537156dfeb91dbac8ffed4db6c4fa1a3164cc9]
#
# patch "sqlite/insert.c"
# from [63f01d3f4e0ba7ed171934a24aece2191824faec]
# to [e9526ced19978a55687b55faea969b6ff2a53fb4]
#
# patch "sqlite/legacy.c"
# from [10e01a902d7f2c872c7922fedf19a2df70935857]
# to [2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6]
#
# patch "sqlite/loadext.c"
# from [040853b36adf535bba6a2e9f5d921422a4394baf]
# to [d7f0903ba15d7a713fc42943e72178cae8ad922b]
#
# patch "sqlite/main.c"
# from [3690d4a440c0bfba7b4816d52869e17b9adccb58]
# to [33c32014da3a1471e8869d2eba32b2c4314c39ce]
#
# patch "sqlite/opcodes.c"
# from [4ad0e1f98ddf401a638d077148a2b859fdf9b240]
# to [b7b90245b9f102a608f7c3472acd5b99610b60e4]
#
# patch "sqlite/opcodes.h"
# from [8cae6122fd7c3c1d506169eee78d3c9108bfaeb5]
# to [fd07578003f350722aa5df4d053fed9d5c4ea80d]
#
# patch "sqlite/os.h"
# from [3fd6a022bafd620fdfd779a51dccb42f31c97f75]
# to [17fc73165cb7436aa79492d2dff754baec74fcb9]
#
# patch "sqlite/os_common.h"
# from [108cd719c96a2b714b64e02aeabbd40684274e6a]
# to [545426356f0868a6765e70cb59e319d3acad0ed6]
#
# patch "sqlite/os_os2.c"
# from [1cf00781716ae8f9ae1d886e819c55731249b3a8]
# to [1ece434c4817e2925318954336cfe1731713beb0]
#
# patch "sqlite/os_unix.c"
# from [17d91581a0ab478a06cb6f257b707a4c4a93e5a7]
# to [9fbbd8ab0a6b3992370ba0f3aae11feff2a78c96]
#
# patch "sqlite/os_win.c"
# from [c6976ae50b61fb5b7dce399e578aa1865f02b84f]
# to [92df146ed964401969831a19bb490d76ce4de4c0]
#
# patch "sqlite/pager.c"
# from [e51c079b3cad8394898a6c22330150339103700a]
# to [48296c371c44bf43f1c02e221142149797f33072]
#
# patch "sqlite/pager.h"
# from [0cff9de5e9019cb695a04d18df8caaaff933a272]
# to [2e6d42f4ae004ae748a037b8468112b851c447a7]
#
# patch "sqlite/parse.c"
# from [74b46eaf63659f557b1b7378a67461e52276c6c1]
# to [ce2f4b581ae27ae7b5469855cb3497935f9a3984]
#
# patch "sqlite/pragma.c"
# from [cc12939bb74a6e28eb2e867e75175eecffe089a1]
# to [d0891d3504b6291b506a5ec2226bbf79ffcef003]
#
# patch "sqlite/prepare.c"
# from [84e2c855600c7bfbe2ca691b263301de525f9123]
# to [f4f45b4560defbb566cf8255763625d2c09a8023]
#
# patch "sqlite/select.c"
# from [0d4724930a1f34c747105ed1802fa4af0d8eb519]
# to [52f09127b53697b1a95835a9b0db9309cca8079f]
#
# patch "sqlite/sqlite3.h"
# from [63537552e037a5f8771735da3bd49ef03a4aef9a]
# to [9d3ddb04e2bb107eac50266b2dafcf27a03ec5c1]
#
# patch "sqlite/sqlite3ext.h"
# from [5d0b018f61b42caaead89ce1dfa93f5daea29f8c]
# to [2c2156cc32a158e2b7bd9042d42accf94bff2e40]
#
# patch "sqlite/sqliteInt.h"
# from [85975cbb95777f619fd76f1ba728022f13321e1b]
# to [90dad3c0ba7a5151c48361748ccdada9ff2eff78]
#
# patch "sqlite/table.c"
# from [d8817f43a6c6bf139487db161760b9e1e02da3f1]
# to [6d0da66dde26ee75614ed8f584a1996467088d06]
#
# patch "sqlite/trigger.c"
# from [0fc40125820409a6274834a6e04ad804d96e2793]
# to [8c55d31876013ed4e97ee7ce24478fbe00db49bb]
#
# patch "sqlite/utf.c"
# from [4459801e9b00cfd69993bfca58545d3775682d6e]
# to [67ecb1032bc0b42c105e88d65ef9d9f626eb0e1f]
#
# patch "sqlite/util.c"
# from [5409031819ee4672c5f9c3ac7cf517e267a25845]
# to [91d4cb189476906639ae611927d939691d1365f6]
#
# patch "sqlite/vacuum.c"
# from [5b37d0f436f8e1ffacd17934e44720b38d2247f9]
# to [b4569b08aaa5afb141af3f76d0315745db4e9e4b]
#
# patch "sqlite/vdbe.c"
# from [3cea0b930abca02facd4c01fc6f369015730a926]
# to [180ea84f8087d4b56ccc4c4d496d4558cfaf4450]
#
# patch "sqlite/vdbe.h"
# from [258b5d1c0aaa72192f09ff0568ce42b383f156fa]
# to [9720cae673359dc2bdcb106285ecf686b7d3ef24]
#
# patch "sqlite/vdbeInt.h"
# from [e3eaab262b67b84474625cfc38aec1125c32834b]
# to [1ca07f2d7446c90230346aed7fbf990c032460bc]
#
# patch "sqlite/vdbeapi.c"
# from [81f531d7dc5c898131b02ef85f6c6144ab2892cf]
# to [2d1e6843af8705a1172e54a418d2a3d5febd1dd7]
#
# patch "sqlite/vdbeaux.c"
# from [d56304b50c912faefd9f88dff621391310ed2fc5]
# to [05cc6f0f82b86dfb4c356e06ab07ec8cc83a2eda]
#
# patch "sqlite/vdbemem.c"
# from [5f0afe3b92bb2c037f8d5d697f7c151fa50783a3]
# to [26623176bf1c616aa478da958fac49502491a921]
#
# patch "sqlite/vtab.c"
# from [cae036dc7b0b7d7f5f17eef646b1d53940a21572]
# to [aa30e940058ea56a1b7a9a7019ec21d307316fb4]
#
# patch "sqlite/where.c"
# from [75a89957fcb8c068bec55caa4e9d2ed5fa0b0724]
# to [f55d4459a122457a135cf9ec859bf28777d9156f]
#
============================================================
--- ChangeLog 3cb7bfb9055fc1669cb3bce2a8b6494d9a4b6107
+++ ChangeLog 65ed20b61dbbcf7cb783764fddde4c8490b34952
@@ -1,3 +1,7 @@
+2007-01-09 Matthew Gregan
+
+ * sqlite/*: Import SQLite 3.3.9.
+
2007-01-08 Richard Levitte
* debian/control (Build-Depends-Indep): Have texlive-base-bin as
============================================================
--- sqlite/alter.c eba661e77bfd00282fbfa316cdb6aef04856fedc
+++ sqlite/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3
@@ -12,7 +12,7 @@
** This file contains C code routines that used to generate VDBE code
** that implements the ALTER TABLE command.
**
-** $Id: alter.c,v 1.21 2006/06/21 12:36:25 danielk1977 Exp $
+** $Id: alter.c,v 1.22 2006/09/08 12:27:37 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -28,7 +28,7 @@
** 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
+** the CREATE TABLE or CREATE INDEX statement is replaced with the third
** argument and the result returned. Examples:
**
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
@@ -78,10 +78,10 @@ static void renameTableFunc(
}
#ifndef SQLITE_OMIT_TRIGGER
-/* This function is used by SQL generated to implement the ALTER TABLE
+/* This function is used by SQL generated to implement the
** 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
+** TRIGGER statement is replaced with the third argument and the result
** returned. This is analagous to renameTableFunc() above, except for CREATE
** TRIGGER, not CREATE INDEX and CREATE TABLE.
*/
============================================================
--- sqlite/btree.c c4757940df58fc0914d2c4f1778a66101df2c6b9
+++ sqlite/btree.c e7d1694ad0844918e20b802a249533789bf811dc
@@ -9,7 +9,7 @@
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.326 2006/08/08 13:51:43 drh Exp $
+** $Id: btree.c,v 1.332 2006/12/18 18:34:51 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
@@ -387,17 +387,13 @@ struct BtCursor {
CellInfo info; /* A parse of the cell we are pointing at */
u8 wrFlag; /* True if writable */
u8 eState; /* One of the CURSOR_XXX constants (see below) */
-#ifndef SQLITE_OMIT_SHARED_CACHE
void *pKey; /* Saved key that was cursor's last known position */
i64 nKey; /* Size of pKey, or last integer key */
int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */
-#endif
};
/*
-** Potential values for BtCursor.eState. The first two values (VALID and
-** INVALID) may occur in any build. The third (REQUIRESEEK) may only occur
-** if sqlite was compiled without the OMIT_SHARED_CACHE symbol defined.
+** Potential values for BtCursor.eState.
**
** CURSOR_VALID:
** Cursor points to a valid entry. getPayload() etc. may be called.
@@ -425,7 +421,8 @@ struct BtCursor {
*/
#if SQLITE_TEST
# define TRACE(X) if( sqlite3_btree_trace )\
- { sqlite3DebugPrintf X; fflush(stdout); }
+/* { sqlite3DebugPrintf X; fflush(stdout); } */ \
+{ printf X; fflush(stdout); }
int sqlite3_btree_trace=0; /* True to enable tracing */
#else
# define TRACE(X)
@@ -434,7 +431,7 @@ int sqlite3_btree_trace=0; /* True to e
/*
** Forward declaration
*/
-static int checkReadLocks(BtShared*,Pgno,BtCursor*);
+static int checkReadLocks(Btree*,Pgno,BtCursor*);
/*
** Read or write a two- and four-byte big-endian integer values.
@@ -509,107 +506,10 @@ struct BtLock {
#define queryTableLock(a,b,c) SQLITE_OK
#define lockTable(a,b,c) SQLITE_OK
#define unlockAllTables(a)
- #define restoreOrClearCursorPosition(a,b) SQLITE_OK
- #define saveAllCursors(a,b,c) SQLITE_OK
-
#else
-static void releasePage(MemPage *pPage);
/*
-** Save the current cursor position in the variables BtCursor.nKey
-** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
-*/
-static int saveCursorPosition(BtCursor *pCur){
- int rc;
-
- assert( CURSOR_VALID==pCur->eState );
- assert( 0==pCur->pKey );
-
- rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
-
- /* If this is an intKey table, then the above call to BtreeKeySize()
- ** stores the integer key in pCur->nKey. In this case this value is
- ** all that is required. Otherwise, if pCur is not open on an intKey
- ** table, then malloc space for and store the pCur->nKey bytes of key
- ** data.
- */
- if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
- void *pKey = sqliteMalloc(pCur->nKey);
- if( pKey ){
- rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
- if( rc==SQLITE_OK ){
- pCur->pKey = pKey;
- }else{
- sqliteFree(pKey);
- }
- }else{
- rc = SQLITE_NOMEM;
- }
- }
- assert( !pCur->pPage->intKey || !pCur->pKey );
-
- if( rc==SQLITE_OK ){
- releasePage(pCur->pPage);
- pCur->pPage = 0;
- pCur->eState = CURSOR_REQUIRESEEK;
- }
-
- return rc;
-}
-
-/*
-** Save the positions of all cursors except pExcept open on the table
-** with root-page iRoot. Usually, this is called just before cursor
-** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
-*/
-static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
- BtCursor *p;
- if( sqlite3ThreadDataReadOnly()->useSharedData ){
- for(p=pBt->pCursor; p; p=p->pNext){
- if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
- p->eState==CURSOR_VALID ){
- int rc = saveCursorPosition(p);
- if( SQLITE_OK!=rc ){
- return rc;
- }
- }
- }
- }
- return SQLITE_OK;
-}
-
-/*
-** Restore the cursor to the position it was in (or as close to as possible)
-** when saveCursorPosition() was called. Note that this call deletes the
-** saved position info stored by saveCursorPosition(), so there can be
-** at most one effective restoreOrClearCursorPosition() call after each
-** saveCursorPosition().
-**
-** If the second argument argument - doSeek - is false, then instead of
-** returning the cursor to it's saved position, any saved position is deleted
-** and the cursor state set to CURSOR_INVALID.
-*/
-static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
- int rc = SQLITE_OK;
- assert( sqlite3ThreadDataReadOnly()->useSharedData );
- assert( pCur->eState==CURSOR_REQUIRESEEK );
- pCur->eState = CURSOR_INVALID;
- if( doSeek ){
- rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
- }
- if( rc==SQLITE_OK ){
- sqliteFree(pCur->pKey);
- pCur->pKey = 0;
- assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
- }
- return rc;
-}
-
-#define restoreOrClearCursorPosition(p,x) \
- (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
-
-/*
** Query to see if btree handle p may obtain a lock of type eLock
** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return
** SQLITE_OK if the lock may be obtained (by calling lockTable()), or
@@ -747,6 +647,98 @@ static void unlockAllTables(Btree *p){
}
#endif /* SQLITE_OMIT_SHARED_CACHE */
+static void releasePage(MemPage *pPage); /* Forward reference */
+
+/*
+** Save the current cursor position in the variables BtCursor.nKey
+** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
+*/
+static int saveCursorPosition(BtCursor *pCur){
+ int rc;
+
+ assert( CURSOR_VALID==pCur->eState );
+ assert( 0==pCur->pKey );
+
+ rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
+
+ /* If this is an intKey table, then the above call to BtreeKeySize()
+ ** stores the integer key in pCur->nKey. In this case this value is
+ ** all that is required. Otherwise, if pCur is not open on an intKey
+ ** table, then malloc space for and store the pCur->nKey bytes of key
+ ** data.
+ */
+ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
+ void *pKey = sqliteMalloc(pCur->nKey);
+ if( pKey ){
+ rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
+ if( rc==SQLITE_OK ){
+ pCur->pKey = pKey;
+ }else{
+ sqliteFree(pKey);
+ }
+ }else{
+ rc = SQLITE_NOMEM;
+ }
+ }
+ assert( !pCur->pPage->intKey || !pCur->pKey );
+
+ if( rc==SQLITE_OK ){
+ releasePage(pCur->pPage);
+ pCur->pPage = 0;
+ pCur->eState = CURSOR_REQUIRESEEK;
+ }
+
+ return rc;
+}
+
+/*
+** Save the positions of all cursors except pExcept open on the table
+** with root-page iRoot. Usually, this is called just before cursor
+** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
+*/
+static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
+ BtCursor *p;
+ for(p=pBt->pCursor; p; p=p->pNext){
+ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) &&
+ p->eState==CURSOR_VALID ){
+ int rc = saveCursorPosition(p);
+ if( SQLITE_OK!=rc ){
+ return rc;
+ }
+ }
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Restore the cursor to the position it was in (or as close to as possible)
+** when saveCursorPosition() was called. Note that this call deletes the
+** saved position info stored by saveCursorPosition(), so there can be
+** at most one effective restoreOrClearCursorPosition() call after each
+** saveCursorPosition().
+**
+** If the second argument argument - doSeek - is false, then instead of
+** returning the cursor to it's saved position, any saved position is deleted
+** and the cursor state set to CURSOR_INVALID.
+*/
+static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
+ int rc = SQLITE_OK;
+ assert( pCur->eState==CURSOR_REQUIRESEEK );
+ pCur->eState = CURSOR_INVALID;
+ if( doSeek ){
+ rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
+ }
+ if( rc==SQLITE_OK ){
+ sqliteFree(pCur->pKey);
+ pCur->pKey = 0;
+ assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState );
+ }
+ return rc;
+}
+
+#define restoreOrClearCursorPosition(p,x) \
+ (p->eState==CURSOR_REQUIRESEEK?restoreOrClearCursorPositionX(p,x):SQLITE_OK)
+
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** These macros define the location of the pointer-map entry for a
@@ -1048,91 +1040,6 @@ static int ptrmapPutOvfl(MemPage *pPage,
#endif
-/*
-** Do sanity checking on a page. Throw an exception if anything is
-** not right.
-**
-** This routine is used for internal error checking only. It is omitted
-** from most builds.
-*/
-#if defined(BTREE_DEBUG) && !defined(NDEBUG) && 0
-static void _pageIntegrity(MemPage *pPage){
- int usableSize;
- u8 *data;
- int i, j, idx, c, pc, hdr, nFree;
- int cellOffset;
- int nCell, cellLimit;
- u8 *used;
-
- used = sqliteMallocRaw( pPage->pBt->pageSize );
- if( used==0 ) return;
- usableSize = pPage->pBt->usableSize;
- assert( pPage->aData==&((unsigned char*)pPage)[-pPage->pBt->pageSize] );
- hdr = pPage->hdrOffset;
- assert( hdr==(pPage->pgno==1 ? 100 : 0) );
- assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
- c = pPage->aData[hdr];
- if( pPage->isInit ){
- assert( pPage->leaf == ((c & PTF_LEAF)!=0) );
- assert( pPage->zeroData == ((c & PTF_ZERODATA)!=0) );
- assert( pPage->leafData == ((c & PTF_LEAFDATA)!=0) );
- assert( pPage->intKey == ((c & (PTF_INTKEY|PTF_LEAFDATA))!=0) );
- assert( pPage->hasData ==
- !(pPage->zeroData || (!pPage->leaf && pPage->leafData)) );
- assert( pPage->cellOffset==pPage->hdrOffset+12-4*pPage->leaf );
- assert( pPage->nCell = get2byte(&pPage->aData[hdr+3]) );
- }
- data = pPage->aData;
- memset(used, 0, usableSize);
- for(i=0; ileaf*4; i++) used[i] = 1;
- nFree = 0;
- pc = get2byte(&data[hdr+1]);
- while( pc ){
- int size;
- assert( pc>0 && pcisInit==0
- || pPage->nFree==nFree+data[hdr+7]+cellLimit-(cellOffset+2*nCell) );
- cellOffset = pPage->cellOffset;
- for(i=0; i0 && pcisInit = 1;
- pageIntegrity(pPage);
return SQLITE_OK;
}
@@ -1470,7 +1376,6 @@ static void zeroPage(MemPage *pPage, int
pPage->idxShift = 0;
pPage->nCell = 0;
pPage->isInit = 1;
- pageIntegrity(pPage);
}
/*
@@ -1591,9 +1496,9 @@ int sqlite3BtreeOpen(
*/
#if !defined(SQLITE_OMIT_SHARED_CACHE) || !defined(SQLITE_OMIT_AUTOVACUUM)
#ifdef SQLITE_OMIT_MEMORYDB
- const int isMemdb = !zFilename;
+ const int isMemdb = 0;
#else
- const int isMemdb = !zFilename || (strcmp(zFilename, ":memory:")?0:1);
+ const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
#endif
#endif
@@ -1645,8 +1550,13 @@ int sqlite3BtreeOpen(
return SQLITE_NOMEM;
}
rc = sqlite3pager_open(&pBt->pPager, zFilename, EXTRA_SIZE, flags);
+ if( rc==SQLITE_OK ){
+ rc = sqlite3pager_read_fileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
+ }
if( rc!=SQLITE_OK ){
- if( pBt->pPager ) sqlite3pager_close(pBt->pPager);
+ if( pBt->pPager ){
+ sqlite3pager_close(pBt->pPager);
+ }
sqliteFree(pBt);
sqliteFree(p);
*ppBtree = 0;
@@ -1659,7 +1569,6 @@ int sqlite3BtreeOpen(
pBt->pCursor = 0;
pBt->pPage1 = 0;
pBt->readOnly = sqlite3pager_isreadonly(pBt->pPager);
- sqlite3pager_read_fileheader(pBt->pPager, sizeof(zDbHeader), zDbHeader);
pBt->pageSize = get2byte(&zDbHeader[16]);
if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
|| ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
@@ -2548,7 +2457,7 @@ static int countWriteCursors(BtShared *p
}
#endif
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/*
** Print debugging information about all cursors to standard output.
*/
@@ -2778,7 +2687,7 @@ int sqlite3BtreeCursor(
if( pBt->readOnly ){
return SQLITE_READONLY;
}
- if( checkReadLocks(pBt, iTable, 0) ){
+ if( checkReadLocks(p, iTable, 0) ){
return SQLITE_LOCKED;
}
}
@@ -2980,7 +2889,6 @@ static int getPayload(
assert( pCur->eState==CURSOR_VALID );
pBt = pCur->pBtree->pBt;
pPage = pCur->pPage;
- pageIntegrity(pPage);
assert( pCur->idx>=0 && pCur->idxnCell );
getCellInfo(pCur);
aPayload = pCur->info.pCell + pCur->info.nHeader;
@@ -3118,7 +3026,6 @@ static const unsigned char *fetchPayload
assert( pCur!=0 && pCur->pPage!=0 );
assert( pCur->eState==CURSOR_VALID );
pPage = pCur->pPage;
- pageIntegrity(pPage);
assert( pCur->idx>=0 && pCur->idxnCell );
getCellInfo(pCur);
aPayload = pCur->info.pCell;
@@ -3180,7 +3087,6 @@ static int moveToChild(BtCursor *pCur, u
assert( pCur->eState==CURSOR_VALID );
rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
if( rc ) return rc;
- pageIntegrity(pNewPage);
pNewPage->idxParent = pCur->idx;
pOldPage = pCur->pPage;
pOldPage->idxShift = 0;
@@ -3228,10 +3134,8 @@ static void moveToParent(BtCursor *pCur)
pPage = pCur->pPage;
assert( pPage!=0 );
assert( !isRootPage(pPage) );
- pageIntegrity(pPage);
pParent = pPage->pParent;
assert( pParent!=0 );
- pageIntegrity(pParent);
idxParent = pPage->idxParent;
sqlite3pager_ref(pParent->aData);
releasePage(pPage);
@@ -3261,7 +3165,6 @@ static int moveToRoot(BtCursor *pCur){
return rc;
}
releasePage(pCur->pPage);
- pageIntegrity(pRoot);
pCur->pPage = pRoot;
}
pCur->idx = 0;
@@ -3405,7 +3308,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, c
assert( pCur->pPage->nCell==0 );
return SQLITE_OK;
}
- for(;;){
+ for(;;){
int lwr, upr;
Pgno chldPg;
MemPage *pPage = pCur->pPage;
@@ -3415,7 +3318,6 @@ int sqlite3BtreeMoveto(BtCursor *pCur, c
if( !pPage->intKey && pKey==0 ){
return SQLITE_CORRUPT_BKPT;
}
- pageIntegrity(pPage);
while( lwr<=upr ){
void *pCellKey;
i64 nCellKey;
@@ -3668,14 +3570,14 @@ static int allocatePage(
int rc;
int n; /* Number of pages on the freelist */
int k; /* Number of leaves on the trunk of the freelist */
+ MemPage *pTrunk = 0;
+ MemPage *pPrevTrunk = 0;
pPage1 = pBt->pPage1;
n = get4byte(&pPage1->aData[36]);
if( n>0 ){
/* There are pages on the freelist. Reuse one of those pages. */
- 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
@@ -3716,24 +3618,20 @@ static int allocatePage(
}
rc = getPage(pBt, iTrunk, &pTrunk);
if( rc ){
- releasePage(pPrevTrunk);
- return rc;
+ pTrunk = 0;
+ goto end_allocate_page;
}
- /* 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 );
+ rc = sqlite3pager_write(pTrunk->aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
*pPgno = iTrunk;
memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
*ppPage = pTrunk;
@@ -3741,7 +3639,8 @@ static int allocatePage(
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;
+ rc = SQLITE_CORRUPT_BKPT;
+ goto end_allocate_page;
#ifndef SQLITE_OMIT_AUTOVACUUM
}else if( searchList && nearby==iTrunk ){
/* The list is being searched and this trunk page is the page
@@ -3750,6 +3649,10 @@ static int allocatePage(
assert( *pPgno==iTrunk );
*ppPage = pTrunk;
searchList = 0;
+ rc = sqlite3pager_write(pTrunk->aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
if( k==0 ){
if( !pPrevTrunk ){
memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
@@ -3765,26 +3668,26 @@ static int allocatePage(
Pgno iNewTrunk = get4byte(&pTrunk->aData[8]);
rc = getPage(pBt, iNewTrunk, &pNewTrunk);
if( rc!=SQLITE_OK ){
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- return rc;
+ goto end_allocate_page;
}
rc = sqlite3pager_write(pNewTrunk->aData);
if( rc!=SQLITE_OK ){
releasePage(pNewTrunk);
- releasePage(pTrunk);
- releasePage(pPrevTrunk);
- return rc;
+ goto end_allocate_page;
}
memcpy(&pNewTrunk->aData[0], &pTrunk->aData[0], 4);
put4byte(&pNewTrunk->aData[4], k-1);
memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4);
+ releasePage(pNewTrunk);
if( !pPrevTrunk ){
put4byte(&pPage1->aData[32], iNewTrunk);
}else{
+ rc = sqlite3pager_write(pPrevTrunk->aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
put4byte(&pPrevTrunk->aData[0], iNewTrunk);
}
- releasePage(pNewTrunk);
}
pTrunk = 0;
TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
@@ -3794,6 +3697,10 @@ static int allocatePage(
int closest;
Pgno iPage;
unsigned char *aData = pTrunk->aData;
+ rc = sqlite3pager_write(aData);
+ if( rc ){
+ goto end_allocate_page;
+ }
if( nearby>0 ){
int i, dist;
closest = 0;
@@ -3837,8 +3744,8 @@ static int allocatePage(
}
}
releasePage(pPrevTrunk);
+ pPrevTrunk = 0;
}while( searchList );
- releasePage(pTrunk);
}else{
/* There are no pages on the freelist, so create a new page at the
** end of the file */
@@ -3867,6 +3774,10 @@ static int allocatePage(
}
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
+
+end_allocate_page:
+ releasePage(pTrunk);
+ releasePage(pPrevTrunk);
return rc;
}
@@ -4267,7 +4178,6 @@ static int insertCell(
put2byte(&data[ins], idx);
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
@@ -5007,8 +4917,6 @@ static int balance_nonroot(MemPage *pPag
** But the parent page will always be initialized.
*/
assert( pParent->isInit );
- /* assert( pPage->isInit ); // No! pPage might have been added to freelist */
- /* pageIntegrity(pPage); // No! pPage might have been added to freelist */
rc = balance(pParent, 0);
/*
@@ -5215,27 +5123,35 @@ static int balance(MemPage *pPage, int i
/*
** This routine checks all cursors that point to table pgnoRoot.
-** If any of those cursors other than pExclude were opened with
-** wrFlag==0 then this routine returns SQLITE_LOCKED. If all
-** cursors that point to pgnoRoot were opened with wrFlag==1
-** then this routine returns SQLITE_OK.
+** If any of those cursors were opened with wrFlag==0 in a different
+** database connection (a database connection that shares the pager
+** cache with the current connection) and that other connection
+** is not in the ReadUncommmitted state, then this routine returns
+** SQLITE_LOCKED.
**
** In addition to checking for read-locks (where a read-lock
** means a cursor opened with wrFlag==0) this routine also moves
-** all cursors other than pExclude so that they are pointing to the
-** first Cell on root page. This is necessary because an insert
+** all cursors write cursors so that they are pointing to the
+** first Cell on the root page. This is necessary because an insert
** or delete might change the number of cells on a page or delete
** a page entirely and we do not want to leave any cursors
** pointing to non-existant pages or cells.
*/
-static int checkReadLocks(BtShared *pBt, Pgno pgnoRoot, BtCursor *pExclude){
+static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
BtCursor *p;
+ BtShared *pBt = pBtree->pBt;
+ sqlite3 *db = pBtree->pSqlite;
for(p=pBt->pCursor; p; p=p->pNext){
- u32 flags = (p->pBtree->pSqlite ? p->pBtree->pSqlite->flags : 0);
- if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue;
- if( p->wrFlag==0 && flags&SQLITE_ReadUncommitted ) continue;
- if( p->wrFlag==0 ) return SQLITE_LOCKED;
- if( p->pPage->pgno!=p->pgnoRoot ){
+ if( p==pExclude ) continue;
+ if( p->eState!=CURSOR_VALID ) continue;
+ if( p->pgnoRoot!=pgnoRoot ) continue;
+ if( p->wrFlag==0 ){
+ sqlite3 *dbOther = p->pBtree->pSqlite;
+ if( dbOther==0 ||
+ (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
+ return SQLITE_LOCKED;
+ }
+ }else if( p->pPage->pgno!=p->pgnoRoot ){
moveToRoot(p);
}
}
@@ -5272,7 +5188,7 @@ int sqlite3BtreeInsert(
if( !pCur->wrFlag ){
return SQLITE_PERM; /* Cursor not open for writing */
}
- if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
+ if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
return SQLITE_LOCKED; /* The table pCur points to has a read lock */
}
@@ -5354,7 +5270,7 @@ int sqlite3BtreeDelete(BtCursor *pCur){
if( !pCur->wrFlag ){
return SQLITE_PERM; /* Did not open this cursor for writing */
}
- if( checkReadLocks(pBt, pCur->pgnoRoot, pCur) ){
+ if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
return SQLITE_LOCKED; /* The table pCur points to has a read lock */
}
@@ -5631,25 +5547,13 @@ int sqlite3BtreeClearTable(Btree *p, int
*/
int sqlite3BtreeClearTable(Btree *p, int iTable){
int rc;
- BtCursor *pCur;
BtShared *pBt = p->pBt;
- sqlite3 *db = p->pSqlite;
if( p->inTrans!=TRANS_WRITE ){
return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
}
-
- /* If this connection is not in read-uncommitted mode and currently has
- ** a read-cursor open on the table being cleared, return SQLITE_LOCKED.
- */
- if( 0==db || 0==(db->flags&SQLITE_ReadUncommitted) ){
- for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
- if( pCur->pBtree==p && pCur->pgnoRoot==(Pgno)iTable ){
- if( 0==pCur->wrFlag ){
- return SQLITE_LOCKED;
- }
- moveToRoot(pCur);
- }
- }
+ rc = checkReadLocks(p, iTable, 0);
+ if( rc ){
+ return rc;
}
/* Save the position of all cursors open on this table */
@@ -5969,7 +5873,7 @@ int sqlite3BtreePageDump(Btree *p, int p
}
#endif
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
/*
** Fill aResult[] with information about the entry and page that the
** cursor is pointing to.
@@ -5997,14 +5901,12 @@ int sqlite3BtreeCursorInfo(BtCursor *pCu
return rc;
}
- pageIntegrity(pPage);
assert( pPage->isInit );
getTempCursor(pCur, &tmpCur);
while( upCnt-- ){
moveToParent(&tmpCur);
}
pPage = tmpCur.pPage;
- pageIntegrity(pPage);
aResult[0] = sqlite3pager_pagenumber(pPage->aData);
assert( aResult[0]==pPage->pgno );
aResult[1] = tmpCur.idx;
============================================================
--- sqlite/build.c 2ea8ad0e2e49b3957692588182524e6c390ab5a9
+++ sqlite/build.c 02aedde724dc73295d6e9b8dc29afb5dd38de507
@@ -22,7 +22,7 @@
** COMMIT
** ROLLBACK
**
-** $Id: build.c,v 1.409 2006/07/26 16:22:15 danielk1977 Exp $
+** $Id: build.c,v 1.412 2006/12/16 16:25:15 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -1077,8 +1077,12 @@ void sqlite3AddDefaultValue(Parse *pPars
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
+ Expr *pCopy;
sqlite3ExprDelete(pCol->pDflt);
- pCol->pDflt = sqlite3ExprDup(pExpr);
+ pCol->pDflt = pCopy = sqlite3ExprDup(pExpr);
+ if( pCopy ){
+ sqlite3TokenCopy(&pCopy->span, &pExpr->span);
+ }
}
}
sqlite3ExprDelete(pExpr);
@@ -1586,7 +1590,8 @@ void sqlite3CreateView(
Token *pName1, /* The token that holds the name of the view */
Token *pName2, /* The token that holds the name of the view */
Select *pSelect, /* A SELECT statement that will become the new view */
- int isTemp /* TRUE for a TEMPORARY view */
+ int isTemp, /* TRUE for a TEMPORARY view */
+ int noErr /* Suppress error messages if VIEW already exists */
){
Table *p;
int n;
@@ -1601,7 +1606,7 @@ void sqlite3CreateView(
sqlite3SelectDelete(pSelect);
return;
}
- sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, 0);
+ sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
p = pParse->pNewTable;
if( p==0 || pParse->nErr ){
sqlite3SelectDelete(pSelect);
@@ -2936,15 +2941,6 @@ void sqlite3SrcListAssignCursors(Parse *
}
/*
-** Add an alias to the last identifier on the given identifier list.
-*/
-void sqlite3SrcListAddAlias(SrcList *pList, Token *pToken){
- if( pList && pList->nSrc>0 ){
- pList->a[pList->nSrc-1].zAlias = sqlite3NameFromToken(pToken);
- }
-}
-
-/*
** Delete an entire SrcList including all its substructure.
*/
void sqlite3SrcListDelete(SrcList *pList){
@@ -2964,6 +2960,74 @@ void sqlite3SrcListDelete(SrcList *pList
}
/*
+** This routine is called by the parser to add a new term to the
+** end of a growing FROM clause. The "p" parameter is the part of
+** the FROM clause that has already been constructed. "p" is NULL
+** if this is the first term of the FROM clause. pTable and pDatabase
+** are the name of the table and database named in the FROM clause term.
+** pDatabase is NULL if the database name qualifier is missing - the
+** usual case. If the term has a alias, then pAlias points to the
+** alias token. If the term is a subquery, then pSubquery is the
+** SELECT statement that the subquery encodes. The pTable and
+** pDatabase parameters are NULL for subqueries. The pOn and pUsing
+** parameters are the content of the ON and USING clauses.
+**
+** Return a new SrcList which encodes is the FROM with the new
+** term added.
+*/
+SrcList *sqlite3SrcListAppendFromTerm(
+ SrcList *p, /* The left part of the FROM clause already seen */
+ Token *pTable, /* Name of the table to add to the FROM clause */
+ Token *pDatabase, /* Name of the database containing pTable */
+ Token *pAlias, /* The right-hand side of the AS subexpression */
+ Select *pSubquery, /* A subquery used in place of a table name */
+ Expr *pOn, /* The ON clause of a join */
+ IdList *pUsing /* The USING clause of a join */
+){
+ struct SrcList_item *pItem;
+ p = sqlite3SrcListAppend(p, pTable, pDatabase);
+ if( p==0 || p->nSrc==0 ){
+ sqlite3ExprDelete(pOn);
+ sqlite3IdListDelete(pUsing);
+ sqlite3SelectDelete(pSubquery);
+ return p;
+ }
+ pItem = &p->a[p->nSrc-1];
+ if( pAlias && pAlias->n ){
+ pItem->zAlias = sqlite3NameFromToken(pAlias);
+ }
+ pItem->pSelect = pSubquery;
+ pItem->pOn = pOn;
+ pItem->pUsing = pUsing;
+ return p;
+}
+
+/*
+** When building up a FROM clause in the parser, the join operator
+** is initially attached to the left operand. But the code generator
+** expects the join operator to be on the right operand. This routine
+** Shifts all join operators from left to right for an entire FROM
+** clause.
+**
+** Example: Suppose the join is like this:
+**
+** A natural cross join B
+**
+** The operator is "natural cross join". The A and B operands are stored
+** in p->a[0] and p->a[1], respectively. The parser initially stores the
+** operator with A. This routine shifts that operator over to B.
+*/
+void sqlite3SrcListShiftJoinType(SrcList *p){
+ if( p && p->a ){
+ int i;
+ for(i=p->nSrc-1; i>0; i--){
+ p->a[i].jointype = p->a[i-1].jointype;
+ }
+ p->a[0].jointype = 0;
+ }
+}
+
+/*
** Begin a transaction
*/
void sqlite3BeginTransaction(Parse *pParse, int type){
============================================================
--- sqlite/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
+++ sqlite/date.c 9602457c49210f77f860d1919a8249a3118cd43f
@@ -16,14 +16,14 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.54 2006/01/31 20:49:13 drh Exp $
+** $Id: date.c,v 1.58 2006/09/25 18:05:04 drh Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers. The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
-** calendar system.
+** calendar system.
**
** 1970-01-01 00:00:00 is JD 2440587.5
** 2000-01-01 00:00:00 is JD 2451544.5
@@ -234,11 +234,11 @@ static void computeJD(DateTime *p){
X2 = 30.6001*(M+1);
p->rJD = X1 + X2 + D + B - 1524.5;
p->validJD = 1;
- p->validYMD = 0;
if( p->validHMS ){
p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
if( p->validTZ ){
p->rJD -= p->tz*60/86400.0;
+ p->validYMD = 0;
p->validHMS = 0;
p->validTZ = 0;
}
@@ -357,6 +357,7 @@ static void computeHMS(DateTime *p){
static void computeHMS(DateTime *p){
int Z, s;
if( p->validHMS ) return;
+ computeJD(p);
Z = p->rJD + 0.5;
s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
p->s = 0.001*s;
@@ -393,7 +394,6 @@ static double localtimeOffset(DateTime *
static double localtimeOffset(DateTime *p){
DateTime x, y;
time_t t;
- struct tm *pTm;
x = *p;
computeYMD_HMS(&x);
if( x.Y<1971 || x.Y>=2038 ){
@@ -411,15 +411,31 @@ static double localtimeOffset(DateTime *
x.validJD = 0;
computeJD(&x);
t = (x.rJD-2440587.5)*86400.0 + 0.5;
- sqlite3OsEnterMutex();
- pTm = localtime(&t);
- y.Y = pTm->tm_year + 1900;
- y.M = pTm->tm_mon + 1;
- y.D = pTm->tm_mday;
- y.h = pTm->tm_hour;
- y.m = pTm->tm_min;
- y.s = pTm->tm_sec;
- sqlite3OsLeaveMutex();
+#ifdef HAVE_LOCALTIME_R
+ {
+ struct tm sLocal;
+ localtime_r(&t, &sLocal);
+ y.Y = sLocal.tm_year + 1900;
+ y.M = sLocal.tm_mon + 1;
+ y.D = sLocal.tm_mday;
+ y.h = sLocal.tm_hour;
+ y.m = sLocal.tm_min;
+ y.s = sLocal.tm_sec;
+ }
+#else
+ {
+ struct tm *pTm;
+ sqlite3OsEnterMutex();
+ pTm = localtime(&t);
+ y.Y = pTm->tm_year + 1900;
+ y.M = pTm->tm_mon + 1;
+ y.D = pTm->tm_mday;
+ y.h = pTm->tm_hour;
+ y.m = pTm->tm_min;
+ y.s = pTm->tm_sec;
+ sqlite3OsLeaveMutex();
+ }
+#endif
y.validYMD = 1;
y.validHMS = 1;
y.validJD = 0;
@@ -581,7 +597,7 @@ static int parseModifier(const char *zMo
if( z[0]=='-' ) tx.rJD = -tx.rJD;
computeJD(p);
clearYMD_HMS_TZ(p);
- p->rJD += tx.rJD;
+ p->rJD += tx.rJD;
rc = 0;
break;
}
@@ -809,9 +825,9 @@ static void strftimeFunc(
switch( zFmt[i] ){
case 'd': sprintf(&z[j],"%02d",x.D); j+=2; break;
case 'f': {
- int s = x.s;
- int ms = (x.s - s)*1000.0;
- sprintf(&z[j],"%02d.%03d",s,ms);
+ double s = x.s;
+ if( s>59.999 ) s = 59.999;
+ sqlite3_snprintf(7, &z[j],"%02.3f", s);
j += strlen(&z[j]);
break;
}
@@ -944,9 +960,21 @@ static void currentTimeFunc(
}
#endif
- sqlite3OsEnterMutex();
- strftime(zBuf, 20, zFormat, gmtime(&t));
- sqlite3OsLeaveMutex();
+#ifdef HAVE_GMTIME_R
+ {
+ struct tm sNow;
+ gmtime_r(&t, &sNow);
+ strftime(zBuf, 20, zFormat, &sNow);
+ }
+#else
+ {
+ struct tm *pTm;
+ sqlite3OsEnterMutex();
+ pTm = gmtime(&t);
+ strftime(zBuf, 20, zFormat, pTm);
+ sqlite3OsLeaveMutex();
+ }
+#endif
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
============================================================
--- sqlite/expr.c 715734d8681c5ad179a24156800b5c5646489e05
+++ sqlite/expr.c 3d2cf15fd9aa6b60b67f45504782cce72cd07963
@@ -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.266 2006/07/11 13:15:08 drh Exp $
+** $Id: expr.c,v 1.271 2007/01/04 01:20:29 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -891,22 +891,23 @@ static int lookupName(
pExpr->iColumn = j==pTab->iPKey ? -1 : j;
pExpr->affinity = pTab->aCol[j].affinity;
pExpr->pColl = sqlite3FindCollSeq(db, ENC(db), zColl,-1, 0);
- if( pItem->jointype & JT_NATURAL ){
- /* If this match occurred in the left table of a natural join,
- ** then skip the right table to avoid a duplicate match */
- pItem++;
- i++;
- }
- if( (pUsing = pItem->pUsing)!=0 ){
- /* If this match occurs on a column that is in the USING clause
- ** of a join, skip the search of the right table of the join
- ** to avoid a duplicate match there. */
- int k;
- for(k=0; knId; k++){
- if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
- pItem++;
- i++;
- break;
+ if( inSrc-1 ){
+ if( pItem[1].jointype & JT_NATURAL ){
+ /* If this match occurred in the left table of a natural join,
+ ** then skip the right table to avoid a duplicate match */
+ pItem++;
+ i++;
+ }else if( (pUsing = pItem[1].pUsing)!=0 ){
+ /* If this match occurs on a column that is in the USING clause
+ ** of a join, skip the search of the right table of the join
+ ** to avoid a duplicate match there. */
+ int k;
+ for(k=0; knId; k++){
+ if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
+ pItem++;
+ i++;
+ break;
+ }
}
}
}
@@ -1161,6 +1162,7 @@ static int nameResolverStep(void *pArg,
int wrong_num_args = 0; /* True if wrong number of arguments */
int is_agg = 0; /* True if is an aggregate function */
int i;
+ int auth; /* Authorization to use the function */
int nId; /* Number of characters in function name */
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
@@ -1179,6 +1181,20 @@ static int nameResolverStep(void *pArg,
}else{
is_agg = pDef->xFunc==0;
}
+#ifndef SQLITE_OMIT_AUTHORIZATION
+ if( pDef ){
+ auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
+ if( auth!=SQLITE_OK ){
+ if( auth==SQLITE_DENY ){
+ sqlite3ErrorMsg(pParse, "not authorized to use function: %s",
+ pDef->zName);
+ pNC->nErr++;
+ }
+ pExpr->op = TK_NULL;
+ return 1;
+ }
+ }
+#endif
if( is_agg && !pNC->allowAgg ){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++;
@@ -2192,6 +2208,7 @@ static int analyzeAggregate(void *pArg,
switch( pExpr->op ){
+ case TK_AGG_COLUMN:
case TK_COLUMN: {
/* Check to see if the column is in one of the tables in the FROM
** clause of the aggregate query */
============================================================
--- sqlite/func.c f357a81bcdd83684cb198a8ad96be1c21e29f85c
+++ sqlite/func.c af537156dfeb91dbac8ffed4db6c4fa1a3164cc9
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.132 2006/06/24 11:51:33 danielk1977 Exp $
+** $Id: func.c,v 1.134 2006/09/16 21:45:14 drh Exp $
*/
#include "sqliteInt.h"
#include
@@ -548,20 +548,7 @@ static void versionFunc(
sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC);
}
-/*
-** The MATCH() function is unimplemented. If anybody tries to use it,
-** return an error.
-*/
-static void matchStub(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- static const char zErr[] = "MATCH is not implemented";
- sqlite3_result_error(context, zErr, sizeof(zErr)-1);
-}
-
/*
** EXPERIMENTAL - This is not an official function. The interface may
** change. This function may disappear. Do not write code that depends
@@ -655,14 +642,20 @@ static void soundexFunc(sqlite3_context
};
assert( argc==1 );
zIn = (u8*)sqlite3_value_text(argv[0]);
- if( zIn==0 ) zIn = "";
+ if( zIn==0 ) zIn = (u8*)"";
for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
if( zIn[i] ){
+ u8 prevcode = iCode[zIn[i]&0x7f];
zResult[0] = toupper(zIn[i]);
for(j=1; j<4 && zIn[i]; i++){
int code = iCode[zIn[i]&0x7f];
if( code>0 ){
- zResult[j++] = code + '0';
+ if( code!=prevcode ){
+ prevcode = code;
+ zResult[j++] = code + '0';
+ }
+ }else{
+ prevcode = 0;
}
}
while( j<4 ){
@@ -1037,7 +1030,6 @@ void sqlite3RegisterBuiltinFunctions(sql
{ "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid },
{ "changes", 0, 1, SQLITE_UTF8, 0, changes },
{ "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes },
- { "match", 2, 0, SQLITE_UTF8, 0, matchStub },
#ifdef SQLITE_SOUNDEX
{ "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
@@ -1110,6 +1102,7 @@ void sqlite3RegisterBuiltinFunctions(sql
}
}
sqlite3RegisterDateTimeFunctions(db);
+ sqlite3_overload_function(db, "MATCH", 2);
#ifdef SQLITE_SSE
(void)sqlite3SseFunctions(db);
#endif
============================================================
--- sqlite/insert.c 63f01d3f4e0ba7ed171934a24aece2191824faec
+++ sqlite/insert.c e9526ced19978a55687b55faea969b6ff2a53fb4
@@ -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.170 2006/06/19 03:05:10 danielk1977 Exp $
+** $Id: insert.c,v 1.172 2006/08/29 18:46:14 drh Exp $
*/
#include "sqliteInt.h"
@@ -387,11 +387,9 @@ void sqlite3Insert(
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
- assert( pList!=0 );
srcTab = -1;
useTempTable = 0;
- assert( pList );
- nColumn = pList->nExpr;
+ nColumn = pList ? pList->nExpr : 0;
for(i=0; ia[i].pExpr) ){
goto insert_cleanup;
@@ -402,7 +400,7 @@ void sqlite3Insert(
/* Make sure the number of columns in the source data matches the number
** of columns to be inserted into the table.
*/
- if( pColumn==0 && nColumn!=pTab->nCol ){
+ if( pColumn==0 && nColumn && nColumn!=pTab->nCol ){
sqlite3ErrorMsg(pParse,
"table %S has %d columns but %d values were supplied",
pTabList, 0, pTab->nCol, nColumn);
@@ -455,7 +453,7 @@ void sqlite3Insert(
** key, the set the keyColumn variable to the primary key column index
** in the original table definition.
*/
- if( pColumn==0 ){
+ if( pColumn==0 && nColumn>0 ){
keyColumn = pTab->iPKey;
}
@@ -618,12 +616,12 @@ void sqlite3Insert(
if( pColumn->a[j].idx==i ) break;
}
}
- if( pColumn && j>=pColumn->nId ){
+ if( nColumn==0 || (pColumn && j>=pColumn->nId) ){
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt);
}else if( useTempTable ){
sqlite3VdbeAddOp(v, OP_Column, srcTab, j);
}else if( pSelect ){
- sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
+ sqlite3VdbeAddOp(v, OP_Dup, i+nColumn-j+IsVirtual(pTab), 1);
}else{
sqlite3ExprCode(pParse, pList->a[j].pExpr);
}
============================================================
--- sqlite/legacy.c 10e01a902d7f2c872c7922fedf19a2df70935857
+++ sqlite/legacy.c 2631df6a861f830d6b1c0fe92b9fdd745b2c0cd6
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: legacy.c,v 1.15 2006/06/26 21:35:45 drh Exp $
+** $Id: legacy.c,v 1.16 2006/09/15 07:28:50 drh Exp $
*/
#include "sqliteInt.h"
@@ -131,5 +131,6 @@ exec_out:
*pzErrMsg = 0;
}
+ assert( (rc&db->errMask)==rc );
return rc;
}
============================================================
--- sqlite/loadext.c 040853b36adf535bba6a2e9f5d921422a4394baf
+++ sqlite/loadext.c d7f0903ba15d7a713fc42943e72178cae8ad922b
@@ -17,6 +17,7 @@
#define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */
#include "sqlite3ext.h"
#include "sqliteInt.h"
+#include "os.h"
#include
#include
@@ -89,7 +90,7 @@
** also check to make sure that the pointer to the function is
** not NULL before calling it.
*/
-const sqlite3_api_routines sqlite3_api = {
+const sqlite3_api_routines sqlite3_apis = {
sqlite3_aggregate_context,
sqlite3_aggregate_count,
sqlite3_bind_blob,
@@ -213,31 +214,10 @@ const sqlite3_api_routines sqlite3_api =
** a library that is new enough to support that API.
*************************************************************************
*/
+ sqlite3_overload_function,
};
/*
-** The windows implementation of shared-library loaders
-*/
-#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__)
-# include
-# define SQLITE_LIBRARY_TYPE HANDLE
-# define SQLITE_OPEN_LIBRARY(A) LoadLibrary(A)
-# define SQLITE_FIND_SYMBOL(A,B) GetProcAddress(A,B)
-# define SQLITE_CLOSE_LIBRARY(A) FreeLibrary(A)
-#endif /* windows */
-
-/*
-** The unix implementation of shared-library loaders
-*/
-#if defined(HAVE_DLOPEN) && !defined(SQLITE_LIBRARY_TYPE)
-# include
-# define SQLITE_LIBRARY_TYPE void*
-# define SQLITE_OPEN_LIBRARY(A) dlopen(A, RTLD_NOW | RTLD_GLOBAL)
-# define SQLITE_FIND_SYMBOL(A,B) dlsym(A,B)
-# define SQLITE_CLOSE_LIBRARY(A) dlclose(A)
-#endif
-
-/*
** Attempt to load an SQLite extension library contained in the file
** zFile. The entry point is zProc. zProc may be 0 in which case a
** default entry point name (sqlite3_extension_init) is used. Use
@@ -255,11 +235,10 @@ int sqlite3_load_extension(
const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */
char **pzErrMsg /* Put error message here if not 0 */
){
-#ifdef SQLITE_LIBRARY_TYPE
- SQLITE_LIBRARY_TYPE handle;
+ void *handle;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
- SQLITE_LIBRARY_TYPE *aHandle;
+ void **aHandle;
/* Ticket #1863. To avoid a creating security problems for older
** applications that relink against newer versions of SQLite, the
@@ -278,7 +257,7 @@ int sqlite3_load_extension(
zProc = "sqlite3_extension_init";
}
- handle = SQLITE_OPEN_LIBRARY(zFile);
+ handle = sqlite3OsDlopen(zFile);
if( handle==0 ){
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("unable to open shared library [%s]", zFile);
@@ -286,20 +265,20 @@ int sqlite3_load_extension(
return SQLITE_ERROR;
}
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
- SQLITE_FIND_SYMBOL(handle, zProc);
+ sqlite3OsDlsym(handle, zProc);
if( xInit==0 ){
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("no entry point [%s] in shared library [%s]",
zProc, zFile);
}
- SQLITE_CLOSE_LIBRARY(handle);
+ sqlite3OsDlclose(handle);
return SQLITE_ERROR;
- }else if( xInit(db, &zErrmsg, &sqlite3_api) ){
+ }else if( xInit(db, &zErrmsg, &sqlite3_apis) ){
if( pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
}
sqlite3_free(zErrmsg);
- SQLITE_CLOSE_LIBRARY(handle);
+ sqlite3OsDlclose(handle);
return SQLITE_ERROR;
}
@@ -315,14 +294,8 @@ int sqlite3_load_extension(
sqliteFree(db->aExtension);
db->aExtension = aHandle;
- ((SQLITE_LIBRARY_TYPE*)db->aExtension)[db->nExtension-1] = handle;
+ db->aExtension[db->nExtension-1] = handle;
return SQLITE_OK;
-#else
- if( pzErrMsg ){
- *pzErrMsg = sqlite3_mprintf("extension loading is disabled");
- }
- return SQLITE_ERROR;
-#endif
}
/*
@@ -330,13 +303,11 @@ void sqlite3CloseExtensions(sqlite3 *db)
** to clean up loaded extensions
*/
void sqlite3CloseExtensions(sqlite3 *db){
-#ifdef SQLITE_LIBRARY_TYPE
int i;
for(i=0; inExtension; i++){
- SQLITE_CLOSE_LIBRARY(((SQLITE_LIBRARY_TYPE*)db->aExtension)[i]);
+ sqlite3OsDlclose(db->aExtension[i]);
}
sqliteFree(db->aExtension);
-#endif
}
/*
@@ -352,4 +323,86 @@ int sqlite3_enable_load_extension(sqlite
return SQLITE_OK;
}
+/*
+** A list of automatically loaded extensions.
+**
+** This list is shared across threads, so be sure to hold the
+** mutex while accessing or changing it.
+*/
+static int nAutoExtension = 0;
+static void **aAutoExtension = 0;
+
+
+/*
+** Register a statically linked extension that is automatically
+** loaded by every new database connection.
+*/
+int sqlite3_auto_extension(void *xInit){
+ int i;
+ int rc = SQLITE_OK;
+ sqlite3OsEnterMutex();
+ for(i=0; i=nAutoExtension ){
+ xInit = 0;
+ go = 0;
+ }else{
+ xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+ aAutoExtension[i];
+ }
+ sqlite3OsLeaveMutex();
+ if( xInit && xInit(db, &zErrmsg, &sqlite3_apis) ){
+ sqlite3Error(db, SQLITE_ERROR,
+ "automatic extension loading failed: %s", zErrmsg);
+ go = 0;
+ rc = SQLITE_ERROR;
+ }
+ }
+ return rc;
+}
+
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
============================================================
--- sqlite/main.c 3690d4a440c0bfba7b4816d52869e17b9adccb58
+++ sqlite/main.c 33c32014da3a1471e8869d2eba32b2c4314c39ce
@@ -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.354 2006/07/30 20:50:45 drh Exp $
+** $Id: main.c,v 1.360 2006/12/19 18:57:11 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -223,7 +223,7 @@ const char *sqlite3ErrStr(int rc){
*/
const char *sqlite3ErrStr(int rc){
const char *z;
- switch( rc ){
+ switch( rc & 0xff ){
case SQLITE_ROW:
case SQLITE_DONE:
case SQLITE_OK: z = "not an error"; break;
@@ -541,6 +541,32 @@ int sqlite3_create_function16(
}
#endif
+
+/*
+** Declare that a function has been overloaded by a virtual table.
+**
+** If the function already exists as a regular global function, then
+** this routine is a no-op. If the function does not exist, then create
+** a new one that always throws a run-time error.
+**
+** When virtual tables intend to provide an overloaded function, they
+** should call this routine to make sure the global function exists.
+** A global function must exist in order for name resolution to work
+** properly.
+*/
+int sqlite3_overload_function(
+ sqlite3 *db,
+ const char *zName,
+ int nArg
+){
+ int nName = strlen(zName);
+ if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
+ sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
+ 0, sqlite3InvalidFunction, 0, 0);
+ }
+ return sqlite3ApiExit(db, SQLITE_OK);
+}
+
#ifndef SQLITE_OMIT_TRACE
/*
** Register a trace function. The pArg from the previously registered trace
@@ -763,7 +789,7 @@ int sqlite3_errcode(sqlite3 *db){
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
- return db->errCode;
+ return db->errCode & db->errMask;
}
/*
@@ -841,6 +867,7 @@ static int openDatabase(
/* Allocate the sqlite data structure */
db = sqliteMalloc( sizeof(sqlite3) );
if( db==0 ) goto opendb_out;
+ db->errMask = 0xff;
db->priorNewRowid = 0;
db->magic = SQLITE_MAGIC_BUSY;
db->nDb = 2;
@@ -907,11 +934,30 @@ static int openDatabase(
** is accessed.
*/
if( !sqlite3MallocFailed() ){
+ sqlite3Error(db, SQLITE_OK, 0);
sqlite3RegisterBuiltinFunctions(db);
- sqlite3Error(db, SQLITE_OK, 0);
}
db->magic = SQLITE_MAGIC_OPEN;
+ /* Load automatic extensions - extensions that have been registered
+ ** using the sqlite3_automatic_extension() API.
+ */
+ (void)sqlite3AutoLoadExtensions(db);
+
+#ifdef SQLITE_ENABLE_FTS1
+ {
+ extern int sqlite3Fts1Init(sqlite3*);
+ sqlite3Fts1Init(db);
+ }
+#endif
+
+#ifdef SQLITE_ENABLE_FTS2
+ {
+ extern int sqlite3Fts2Init(sqlite3*);
+ sqlite3Fts2Init(db);
+ }
+#endif
+
opendb_out:
if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
sqlite3_close(db);
@@ -999,6 +1045,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt){
}else{
rc = sqlite3VdbeReset((Vdbe*)pStmt);
sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0);
+ assert( (rc & (sqlite3_db_handle(pStmt)->errMask))==rc );
}
return rc;
}
@@ -1285,3 +1332,11 @@ int sqlite3_sleep(int ms){
int sqlite3_sleep(int ms){
return sqlite3OsSleep(ms);
}
+
+/*
+** Enable or disable the extended result codes.
+*/
+int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+ db->errMask = onoff ? 0xffffffff : 0xff;
+ return SQLITE_OK;
+}
============================================================
--- sqlite/opcodes.c 4ad0e1f98ddf401a638d077148a2b859fdf9b240
+++ sqlite/opcodes.c b7b90245b9f102a608f7c3472acd5b99610b60e4
@@ -34,39 +34,39 @@ const char *const sqlite3OpcodeNames[] =
/* 30 */ "Close",
/* 31 */ "CreateIndex",
/* 32 */ "IsUnique",
- /* 33 */ "IdxIsNull",
- /* 34 */ "NotFound",
- /* 35 */ "Int64",
- /* 36 */ "MustBeInt",
- /* 37 */ "Halt",
- /* 38 */ "Rowid",
- /* 39 */ "IdxLT",
- /* 40 */ "AddImm",
- /* 41 */ "Statement",
- /* 42 */ "RowData",
- /* 43 */ "MemMax",
- /* 44 */ "Push",
- /* 45 */ "NotExists",
- /* 46 */ "MemIncr",
- /* 47 */ "Gosub",
- /* 48 */ "Integer",
- /* 49 */ "MemInt",
- /* 50 */ "Prev",
- /* 51 */ "VColumn",
- /* 52 */ "CreateTable",
- /* 53 */ "Last",
- /* 54 */ "IdxRowid",
- /* 55 */ "MakeIdxRec",
- /* 56 */ "ResetCount",
- /* 57 */ "FifoWrite",
- /* 58 */ "Callback",
- /* 59 */ "ContextPush",
- /* 60 */ "DropTrigger",
+ /* 33 */ "NotFound",
+ /* 34 */ "Int64",
+ /* 35 */ "MustBeInt",
+ /* 36 */ "Halt",
+ /* 37 */ "Rowid",
+ /* 38 */ "IdxLT",
+ /* 39 */ "AddImm",
+ /* 40 */ "Statement",
+ /* 41 */ "RowData",
+ /* 42 */ "MemMax",
+ /* 43 */ "Push",
+ /* 44 */ "NotExists",
+ /* 45 */ "MemIncr",
+ /* 46 */ "Gosub",
+ /* 47 */ "Integer",
+ /* 48 */ "MemInt",
+ /* 49 */ "Prev",
+ /* 50 */ "VColumn",
+ /* 51 */ "CreateTable",
+ /* 52 */ "Last",
+ /* 53 */ "IdxRowid",
+ /* 54 */ "MakeIdxRec",
+ /* 55 */ "ResetCount",
+ /* 56 */ "FifoWrite",
+ /* 57 */ "Callback",
+ /* 58 */ "ContextPush",
+ /* 59 */ "DropTrigger",
+ /* 60 */ "DropIndex",
/* 61 */ "Or",
/* 62 */ "And",
- /* 63 */ "DropIndex",
- /* 64 */ "IdxGE",
- /* 65 */ "IdxDelete",
+ /* 63 */ "IdxGE",
+ /* 64 */ "IdxDelete",
+ /* 65 */ "Vacuum",
/* 66 */ "IsNull",
/* 67 */ "NotNull",
/* 68 */ "Ne",
@@ -75,7 +75,7 @@ const char *const sqlite3OpcodeNames[] =
/* 71 */ "Le",
/* 72 */ "Lt",
/* 73 */ "Ge",
- /* 74 */ "Vacuum",
+ /* 74 */ "MoveLe",
/* 75 */ "BitAnd",
/* 76 */ "BitOr",
/* 77 */ "ShiftLeft",
@@ -87,56 +87,56 @@ const char *const sqlite3OpcodeNames[] =
/* 83 */ "Remainder",
/* 84 */ "Concat",
/* 85 */ "Negative",
- /* 86 */ "MoveLe",
+ /* 86 */ "IfNot",
/* 87 */ "BitNot",
/* 88 */ "String8",
- /* 89 */ "IfNot",
- /* 90 */ "DropTable",
- /* 91 */ "MakeRecord",
- /* 92 */ "Delete",
- /* 93 */ "AggFinal",
- /* 94 */ "Dup",
- /* 95 */ "Goto",
- /* 96 */ "TableLock",
- /* 97 */ "FifoRead",
- /* 98 */ "Clear",
- /* 99 */ "IdxGT",
- /* 100 */ "MoveLt",
- /* 101 */ "VerifyCookie",
- /* 102 */ "AggStep",
- /* 103 */ "Pull",
- /* 104 */ "SetNumColumns",
- /* 105 */ "AbsValue",
- /* 106 */ "Transaction",
- /* 107 */ "VFilter",
- /* 108 */ "VDestroy",
- /* 109 */ "ContextPop",
- /* 110 */ "Next",
- /* 111 */ "IdxInsert",
- /* 112 */ "Distinct",
- /* 113 */ "Insert",
- /* 114 */ "Destroy",
- /* 115 */ "ReadCookie",
- /* 116 */ "ForceInt",
- /* 117 */ "LoadAnalysis",
- /* 118 */ "Explain",
- /* 119 */ "IfMemZero",
- /* 120 */ "OpenPseudo",
- /* 121 */ "OpenEphemeral",
- /* 122 */ "Null",
- /* 123 */ "Blob",
- /* 124 */ "MemStore",
- /* 125 */ "Rewind",
+ /* 89 */ "DropTable",
+ /* 90 */ "MakeRecord",
+ /* 91 */ "Delete",
+ /* 92 */ "AggFinal",
+ /* 93 */ "Dup",
+ /* 94 */ "Goto",
+ /* 95 */ "TableLock",
+ /* 96 */ "FifoRead",
+ /* 97 */ "Clear",
+ /* 98 */ "IdxGT",
+ /* 99 */ "MoveLt",
+ /* 100 */ "VerifyCookie",
+ /* 101 */ "AggStep",
+ /* 102 */ "Pull",
+ /* 103 */ "SetNumColumns",
+ /* 104 */ "AbsValue",
+ /* 105 */ "Transaction",
+ /* 106 */ "VFilter",
+ /* 107 */ "VDestroy",
+ /* 108 */ "ContextPop",
+ /* 109 */ "Next",
+ /* 110 */ "IdxInsert",
+ /* 111 */ "Distinct",
+ /* 112 */ "Insert",
+ /* 113 */ "Destroy",
+ /* 114 */ "ReadCookie",
+ /* 115 */ "ForceInt",
+ /* 116 */ "LoadAnalysis",
+ /* 117 */ "Explain",
+ /* 118 */ "IfMemZero",
+ /* 119 */ "OpenPseudo",
+ /* 120 */ "OpenEphemeral",
+ /* 121 */ "Null",
+ /* 122 */ "Blob",
+ /* 123 */ "MemStore",
+ /* 124 */ "Rewind",
+ /* 125 */ "MoveGe",
/* 126 */ "Real",
/* 127 */ "HexBlob",
- /* 128 */ "MoveGe",
- /* 129 */ "VBegin",
- /* 130 */ "VUpdate",
- /* 131 */ "VCreate",
- /* 132 */ "MemMove",
- /* 133 */ "MemNull",
- /* 134 */ "Found",
- /* 135 */ "NullRow",
+ /* 128 */ "VBegin",
+ /* 129 */ "VUpdate",
+ /* 130 */ "VCreate",
+ /* 131 */ "MemMove",
+ /* 132 */ "MemNull",
+ /* 133 */ "Found",
+ /* 134 */ "NullRow",
+ /* 135 */ "NotUsed_135",
/* 136 */ "NotUsed_136",
/* 137 */ "NotUsed_137",
/* 138 */ "NotUsed_138",
============================================================
--- sqlite/opcodes.h 8cae6122fd7c3c1d506169eee78d3c9108bfaeb5
+++ sqlite/opcodes.h fd07578003f350722aa5df4d053fed9d5c4ea80d
@@ -43,105 +43,105 @@
#define OP_Close 30
#define OP_CreateIndex 31
#define OP_IsUnique 32
-#define OP_IdxIsNull 33
-#define OP_NotFound 34
-#define OP_Int64 35
-#define OP_MustBeInt 36
-#define OP_Halt 37
-#define OP_Rowid 38
-#define OP_IdxLT 39
-#define OP_AddImm 40
-#define OP_Statement 41
-#define OP_RowData 42
-#define OP_MemMax 43
-#define OP_Push 44
+#define OP_NotFound 33
+#define OP_Int64 34
+#define OP_MustBeInt 35
+#define OP_Halt 36
+#define OP_Rowid 37
+#define OP_IdxLT 38
+#define OP_AddImm 39
+#define OP_Statement 40
+#define OP_RowData 41
+#define OP_MemMax 42
+#define OP_Push 43
#define OP_Or 61 /* same as TK_OR */
-#define OP_NotExists 45
-#define OP_MemIncr 46
-#define OP_Gosub 47
+#define OP_NotExists 44
+#define OP_MemIncr 45
+#define OP_Gosub 46
#define OP_Divide 82 /* same as TK_SLASH */
-#define OP_Integer 48
+#define OP_Integer 47
#define OP_ToNumeric 141 /* same as TK_TO_NUMERIC*/
-#define OP_MemInt 49
-#define OP_Prev 50
+#define OP_MemInt 48
+#define OP_Prev 49
#define OP_Concat 84 /* same as TK_CONCAT */
#define OP_BitAnd 75 /* same as TK_BITAND */
-#define OP_VColumn 51
-#define OP_CreateTable 52
-#define OP_Last 53
+#define OP_VColumn 50
+#define OP_CreateTable 51
+#define OP_Last 52
#define OP_IsNull 66 /* same as TK_ISNULL */
-#define OP_IdxRowid 54
-#define OP_MakeIdxRec 55
+#define OP_IdxRowid 53
+#define OP_MakeIdxRec 54
#define OP_ShiftRight 78 /* same as TK_RSHIFT */
-#define OP_ResetCount 56
-#define OP_FifoWrite 57
-#define OP_Callback 58
-#define OP_ContextPush 59
-#define OP_DropTrigger 60
-#define OP_DropIndex 63
-#define OP_IdxGE 64
-#define OP_IdxDelete 65
-#define OP_Vacuum 74
-#define OP_MoveLe 86
-#define OP_IfNot 89
-#define OP_DropTable 90
-#define OP_MakeRecord 91
+#define OP_ResetCount 55
+#define OP_FifoWrite 56
+#define OP_Callback 57
+#define OP_ContextPush 58
+#define OP_DropTrigger 59
+#define OP_DropIndex 60
+#define OP_IdxGE 63
+#define OP_IdxDelete 64
+#define OP_Vacuum 65
+#define OP_MoveLe 74
+#define OP_IfNot 86
+#define OP_DropTable 89
+#define OP_MakeRecord 90
#define OP_ToBlob 140 /* same as TK_TO_BLOB */
-#define OP_Delete 92
-#define OP_AggFinal 93
+#define OP_Delete 91
+#define OP_AggFinal 92
#define OP_ShiftLeft 77 /* same as TK_LSHIFT */
-#define OP_Dup 94
-#define OP_Goto 95
-#define OP_TableLock 96
-#define OP_FifoRead 97
-#define OP_Clear 98
-#define OP_IdxGT 99
-#define OP_MoveLt 100
+#define OP_Dup 93
+#define OP_Goto 94
+#define OP_TableLock 95
+#define OP_FifoRead 96
+#define OP_Clear 97
+#define OP_IdxGT 98
+#define OP_MoveLt 99
#define OP_Le 71 /* same as TK_LE */
-#define OP_VerifyCookie 101
-#define OP_AggStep 102
-#define OP_Pull 103
+#define OP_VerifyCookie 100
+#define OP_AggStep 101
+#define OP_Pull 102
#define OP_ToText 139 /* same as TK_TO_TEXT */
#define OP_Not 16 /* same as TK_NOT */
#define OP_ToReal 143 /* same as TK_TO_REAL */
-#define OP_SetNumColumns 104
-#define OP_AbsValue 105
-#define OP_Transaction 106
-#define OP_VFilter 107
+#define OP_SetNumColumns 103
+#define OP_AbsValue 104
+#define OP_Transaction 105
+#define OP_VFilter 106
#define OP_Negative 85 /* same as TK_UMINUS */
#define OP_Ne 68 /* same as TK_NE */
-#define OP_VDestroy 108
-#define OP_ContextPop 109
+#define OP_VDestroy 107
+#define OP_ContextPop 108
#define OP_BitOr 76 /* same as TK_BITOR */
-#define OP_Next 110
-#define OP_IdxInsert 111
-#define OP_Distinct 112
+#define OP_Next 109
+#define OP_IdxInsert 110
+#define OP_Distinct 111
#define OP_Lt 72 /* same as TK_LT */
-#define OP_Insert 113
-#define OP_Destroy 114
-#define OP_ReadCookie 115
-#define OP_ForceInt 116
-#define OP_LoadAnalysis 117
-#define OP_Explain 118
-#define OP_IfMemZero 119
-#define OP_OpenPseudo 120
-#define OP_OpenEphemeral 121
-#define OP_Null 122
-#define OP_Blob 123
+#define OP_Insert 112
+#define OP_Destroy 113
+#define OP_ReadCookie 114
+#define OP_ForceInt 115
+#define OP_LoadAnalysis 116
+#define OP_Explain 117
+#define OP_IfMemZero 118
+#define OP_OpenPseudo 119
+#define OP_OpenEphemeral 120
+#define OP_Null 121
+#define OP_Blob 122
#define OP_Add 79 /* same as TK_PLUS */
-#define OP_MemStore 124
-#define OP_Rewind 125
-#define OP_MoveGe 128
-#define OP_VBegin 129
-#define OP_VUpdate 130
+#define OP_MemStore 123
+#define OP_Rewind 124
+#define OP_MoveGe 125
+#define OP_VBegin 128
+#define OP_VUpdate 129
#define OP_BitNot 87 /* same as TK_BITNOT */
-#define OP_VCreate 131
-#define OP_MemMove 132
-#define OP_MemNull 133
-#define OP_Found 134
-#define OP_NullRow 135
+#define OP_VCreate 130
+#define OP_MemMove 131
+#define OP_MemNull 132
+#define OP_Found 133
+#define OP_NullRow 134
/* The following opcode values are never used */
+#define OP_NotUsed_135 135
#define OP_NotUsed_136 136
#define OP_NotUsed_137 137
#define OP_NotUsed_138 138
@@ -151,11 +151,11 @@
** set. See the opcodeNoPush() function in vdbeaux.c */
#define NOPUSH_MASK_0 0xeeb4
#define NOPUSH_MASK_1 0x796b
-#define NOPUSH_MASK_2 0xfbb7
-#define NOPUSH_MASK_3 0xff24
+#define NOPUSH_MASK_2 0x7ddb
+#define NOPUSH_MASK_3 0xff92
#define NOPUSH_MASK_4 0xffff
-#define NOPUSH_MASK_5 0xb6ef
-#define NOPUSH_MASK_6 0xfdfd
-#define NOPUSH_MASK_7 0x33b3
-#define NOPUSH_MASK_8 0xf8cf
+#define NOPUSH_MASK_5 0xdaef
+#define NOPUSH_MASK_6 0xfefe
+#define NOPUSH_MASK_7 0x39d9
+#define NOPUSH_MASK_8 0xf867
#define NOPUSH_MASK_9 0x0000
============================================================
--- sqlite/os.h 3fd6a022bafd620fdfd779a51dccb42f31c97f75
+++ sqlite/os.h 17fc73165cb7436aa79492d2dff754baec74fcb9
@@ -81,9 +81,21 @@
** prefix to reflect your program's name, so that if your program exits
** prematurely, old temporary files can be easily identified. This can be done
** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
+**
+** 2006-10-31: The default prefix used to be "sqlite_". But then
+** Mcafee started using SQLite in their anti-virus product and it
+** started putting files with the "sqlite" name in the c:/temp folder.
+** This annoyed many windows users. Those users would then do a
+** Google search for "sqlite", find the telephone numbers of the
+** developers and call to wake them up at night and complain.
+** For this reason, the default name prefix is changed to be "sqlite"
+** spelled backwards. So the temp files are still identified, but
+** anybody smart enough to figure out the code is also likely smart
+** enough to know that calling the developer will not help get rid
+** of the file.
*/
#ifndef TEMP_FILE_PREFIX
-# define TEMP_FILE_PREFIX "sqlite_"
+# define TEMP_FILE_PREFIX "etilqs_"
#endif
/*
@@ -110,6 +122,9 @@
#define sqlite3OsRealloc sqlite3GenericRealloc
#define sqlite3OsFree sqlite3GenericFree
#define sqlite3OsAllocationSize sqlite3GenericAllocationSize
+#define sqlite3OsDlopen sqlite3UnixDlopen
+#define sqlite3OsDlsym sqlite3UnixDlsym
+#define sqlite3OsDlclose sqlite3UnixDlclose
#endif
#if OS_WIN
#define sqlite3OsOpenReadWrite sqlite3WinOpenReadWrite
@@ -132,6 +147,9 @@
#define sqlite3OsRealloc sqlite3GenericRealloc
#define sqlite3OsFree sqlite3GenericFree
#define sqlite3OsAllocationSize sqlite3GenericAllocationSize
+#define sqlite3OsDlopen sqlite3WinDlopen
+#define sqlite3OsDlsym sqlite3WinDlsym
+#define sqlite3OsDlclose sqlite3WinDlclose
#endif
#if OS_OS2
#define sqlite3OsOpenReadWrite sqlite3Os2OpenReadWrite
@@ -154,6 +172,9 @@
#define sqlite3OsRealloc sqlite3GenericRealloc
#define sqlite3OsFree sqlite3GenericFree
#define sqlite3OsAllocationSize sqlite3GenericAllocationSize
+#define sqlite3OsDlopen sqlite3Os2Dlopen
+#define sqlite3OsDlsym sqlite3Os2Dlsym
+#define sqlite3OsDlclose sqlite3Os2Dlclose
#endif
@@ -337,6 +358,9 @@ int sqlite3OsAllocationSize(void *);
void *sqlite3OsRealloc(void *, int);
void sqlite3OsFree(void *);
int sqlite3OsAllocationSize(void *);
+void *sqlite3OsDlopen(const char*);
+void *sqlite3OsDlsym(void*, const char*);
+int sqlite3OsDlclose(void*);
/*
** If the SQLITE_ENABLE_REDEF_IO macro is defined, then the OS-layer
@@ -381,17 +405,27 @@ struct sqlite3OsVtbl {
void *(*xRealloc)(void *, int);
void (*xFree)(void *);
int (*xAllocationSize)(void *);
+
+ void *(*xDlopen)(const char*);
+ void *(*xDlsym)(void*, const char*);
+ int (*xDlclose)(void*);
};
/* Macro used to comment out routines that do not exists when there is
-** no disk I/O
+** no disk I/O or extension loading
*/
#ifdef SQLITE_OMIT_DISKIO
# define IF_DISKIO(X) 0
#else
# define IF_DISKIO(X) X
#endif
+#ifdef SQLITE_OMIT_LOAD_EXTENSION
+# define IF_DLOPEN(X) 0
+#else
+# define IF_DLOPEN(X) X
+#endif
+
#ifdef _SQLITE_OS_C_
/*
** The os.c file implements the global virtual function table.
@@ -416,7 +450,10 @@ struct sqlite3OsVtbl {
sqlite3OsMalloc,
sqlite3OsRealloc,
sqlite3OsFree,
- sqlite3OsAllocationSize
+ sqlite3OsAllocationSize,
+ IF_DLOPEN( sqlite3OsDlopen ),
+ IF_DLOPEN( sqlite3OsDlsym ),
+ IF_DLOPEN( sqlite3OsDlclose ),
};
#else
/*
============================================================
--- sqlite/os_common.h 108cd719c96a2b714b64e02aeabbd40684274e6a
+++ sqlite/os_common.h 545426356f0868a6765e70cb59e319d3acad0ed6
@@ -92,25 +92,25 @@ int sqlite3_diskfull = 0;
int sqlite3_io_error_pending = 0;
int sqlite3_diskfull_pending = 0;
int sqlite3_diskfull = 0;
-#define SimulateIOError(A) \
+#define SimulateIOError(CODE) \
if( sqlite3_io_error_pending ) \
- if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
+ if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); CODE; }
static void local_ioerr(){
sqlite3_io_error_hit = 1; /* Really just a place to set a breakpoint */
}
-#define SimulateDiskfullError \
+#define SimulateDiskfullError(CODE) \
if( sqlite3_diskfull_pending ){ \
if( sqlite3_diskfull_pending == 1 ){ \
local_ioerr(); \
sqlite3_diskfull = 1; \
- return SQLITE_FULL; \
+ CODE; \
}else{ \
sqlite3_diskfull_pending--; \
} \
}
#else
#define SimulateIOError(A)
-#define SimulateDiskfullError
+#define SimulateDiskfullError(A)
#endif
/*
============================================================
--- sqlite/os_os2.c 1cf00781716ae8f9ae1d886e819c55731249b3a8
+++ sqlite/os_os2.c 1ece434c4817e2925318954336cfe1731713beb0
@@ -12,6 +12,12 @@
**
** This file contains code that is specific to OS/2.
*/
+
+#if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
+/* os2safe.h has to be included before os2.h, needed for high mem */
+#include
+#endif
+
#include "sqliteInt.h"
#include "os.h"
@@ -287,10 +293,10 @@ int os2Read( OsFile *id, void *pBuf, int
int os2Read( OsFile *id, void *pBuf, int amt ){
ULONG got;
assert( id!=0 );
- SimulateIOError( SQLITE_IOERR );
+ SimulateIOError( return SQLITE_IOERR );
TRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
DosRead( ((os2File*)id)->h, pBuf, amt, &got );
- return (got == (ULONG)amt) ? SQLITE_OK : SQLITE_IOERR;
+ return (got == (ULONG)amt) ? SQLITE_OK : SQLITE_IOERR_SHORT_READ;
}
/*
@@ -301,8 +307,8 @@ int os2Write( OsFile *id, const void *pB
APIRET rc = NO_ERROR;
ULONG wrote;
assert( id!=0 );
- SimulateIOError( SQLITE_IOERR );
- SimulateDiskfullError;
+ SimulateIOError( return SQLITE_IOERR );
+ SimulateDiskfullError( return SQLITE_FULL );
TRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
while( amt > 0 &&
(rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){
@@ -339,7 +345,7 @@ int sqlite3Os2SyncDirectory( const char
** than UNIX.
*/
int sqlite3Os2SyncDirectory( const char *zDirname ){
- SimulateIOError( SQLITE_IOERR );
+ SimulateIOError( return SQLITE_IOERR );
return SQLITE_OK;
}
@@ -351,7 +357,7 @@ int os2Truncate( OsFile *id, i64 nByte )
ULONG upperBits = nByte>>32;
assert( id!=0 );
TRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte );
- SimulateIOError( SQLITE_IOERR );
+ SimulateIOError( return SQLITE_IOERR );
rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits );
if( rc != NO_ERROR ){
return SQLITE_IOERR;
@@ -368,7 +374,7 @@ int os2FileSize( OsFile *id, i64 *pSize
FILESTATUS3 fsts3FileInfo;
memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
assert( id!=0 );
- SimulateIOError( SQLITE_IOERR );
+ SimulateIOError( return SQLITE_IOERR );
rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
if( rc == NO_ERROR ){
*pSize = fsts3FileInfo.cbFile;
@@ -768,7 +774,24 @@ int allocateOs2File( os2File *pInit, OsF
** with other miscellanous aspects of the operating system interface
****************************************************************************/
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+void *sqlite3Os2Dlopen(const char *zFilename){
+ return 0;
+}
+void *sqlite3Os2Dlsym(void *pHandle, const char *zSymbol){
+ return 0;
+}
+int sqlite3Os2Dlclose(void *pHandle){
+ return 0;
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
+
+/*
** Get information to seed the random number generator. The seed
** is written into the buffer zBuf[256]. The calling function must
** supply a sufficiently large buffer.
============================================================
--- sqlite/os_unix.c 17d91581a0ab478a06cb6f257b707a4c4a93e5a7
+++ sqlite/os_unix.c 9fbbd8ab0a6b3992370ba0f3aae11feff2a78c96
@@ -16,6 +16,8 @@
#include "os.h"
#if OS_UNIX /* This file is used on unix only */
+/* #define SQLITE_ENABLE_LOCKING_STYLE 0 */
+
/*
** These #defines should enable >2GB file support on Posix if the
** underlying operating system supports it. If the OS lacks
@@ -47,6 +49,11 @@
#include
#include
#include
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#include
+#include
+#include
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
/*
** If we are to be thread-safe, include the pthreads header and define
@@ -75,6 +82,9 @@ struct unixFile {
IoMethod const *pMethod; /* Always the first entry */
struct openCnt *pOpen; /* Info about all open fd's on this inode */
struct lockInfo *pLock; /* Info about locks on this inode */
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+ void *lockingContext; /* Locking style specific state */
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
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 */
@@ -346,6 +356,32 @@ static Hash openHash = {SQLITE_HASH_BINA
static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0,
sqlite3ThreadSafeMalloc, sqlite3ThreadSafeFree, 0, 0};
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+/*
+** The locking styles are associated with the different file locking
+** capabilities supported by different file systems.
+**
+** POSIX locking style fully supports shared and exclusive byte-range locks
+** ADP locking only supports exclusive byte-range locks
+** FLOCK only supports a single file-global exclusive lock
+** DOTLOCK isn't a true locking style, it refers to the use of a special
+** file named the same as the database file with a '.lock' extension, this
+** can be used on file systems that do not offer any reliable file locking
+** NO locking means that no locking will be attempted, this is only used for
+** read-only file systems currently
+** UNSUPPORTED means that no locking will be attempted, this is only used for
+** file systems that are known to be unsupported
+*/
+typedef enum {
+ posixLockingStyle = 0, /* standard posix-advisory locks */
+ afpLockingStyle, /* use afp locks */
+ flockLockingStyle, /* use flock() */
+ dotlockLockingStyle, /* use .lock files */
+ noLockingStyle, /* useful for read-only file system */
+ unsupportedLockingStyle /* indicates unsupported file system */
+} sqlite3LockingStyle;
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
#ifdef SQLITE_UNIX_THREADS
/*
** This variable records whether or not threads can override each others
@@ -490,6 +526,8 @@ static void releaseLockInfo(struct lockI
*/
static void releaseLockInfo(struct lockInfo *pLock){
assert( sqlite3OsInMutex(1) );
+ if (pLock == NULL)
+ return;
pLock->nRef--;
if( pLock->nRef==0 ){
sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
@@ -502,6 +540,8 @@ static void releaseOpenCnt(struct openCn
*/
static void releaseOpenCnt(struct openCnt *pOpen){
assert( sqlite3OsInMutex(1) );
+ if (pOpen == NULL)
+ return;
pOpen->nRef--;
if( pOpen->nRef==0 ){
sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
@@ -510,7 +550,78 @@ static void releaseOpenCnt(struct openCn
}
}
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
/*
+** Tests a byte-range locking query to see if byte range locks are
+** supported, if not we fall back to dotlockLockingStyle.
+*/
+static sqlite3LockingStyle sqlite3TestLockingStyle(const char *filePath,
+ int fd) {
+ /* test byte-range lock using fcntl */
+ struct flock lockInfo;
+
+ lockInfo.l_len = 1;
+ lockInfo.l_start = 0;
+ lockInfo.l_whence = SEEK_SET;
+ lockInfo.l_type = F_RDLCK;
+
+ if (fcntl(fd, F_GETLK, (int) &lockInfo) != -1) {
+ return posixLockingStyle;
+ }
+
+ /* testing for flock can give false positives. So if if the above test
+ ** fails, then we fall back to using dot-lock style locking.
+ */
+ return dotlockLockingStyle;
+}
+
+/*
+** Examines the f_fstypename entry in the statfs structure as returned by
+** stat() for the file system hosting the database file, assigns the
+** appropriate locking style based on it's value. These values and
+** assignments are based on Darwin/OSX behavior and have not been tested on
+** other systems.
+*/
+static sqlite3LockingStyle sqlite3DetectLockingStyle(const char *filePath,
+ int fd) {
+
+#ifdef SQLITE_FIXED_LOCKING_STYLE
+ return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE;
+#else
+ struct statfs fsInfo;
+
+ if (statfs(filePath, &fsInfo) == -1)
+ return sqlite3TestLockingStyle(filePath, fd);
+
+ if (fsInfo.f_flags & MNT_RDONLY)
+ return noLockingStyle;
+
+ if( (!strcmp(fsInfo.f_fstypename, "hfs")) ||
+ (!strcmp(fsInfo.f_fstypename, "ufs")) )
+ return posixLockingStyle;
+
+ if(!strcmp(fsInfo.f_fstypename, "afpfs"))
+ return afpLockingStyle;
+
+ if(!strcmp(fsInfo.f_fstypename, "nfs"))
+ return sqlite3TestLockingStyle(filePath, fd);
+
+ if(!strcmp(fsInfo.f_fstypename, "smbfs"))
+ return flockLockingStyle;
+
+ if(!strcmp(fsInfo.f_fstypename, "msdos"))
+ return dotlockLockingStyle;
+
+ if(!strcmp(fsInfo.f_fstypename, "webdav"))
+ return unsupportedLockingStyle;
+
+ return sqlite3TestLockingStyle(filePath, fd);
+#endif // SQLITE_FIXED_LOCKING_STYLE
+}
+
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
+/*
** Given a file descriptor, locate lockInfo and openCnt structures that
** describes that file descriptor. Create new ones if necessary. The
** return values might be uninitialized if an error occurs.
@@ -651,12 +762,16 @@ static int transferOwnership(unixFile *p
}
TRACE4("Transfer ownership of %d from %d to %d\n", pFile->h,pFile->tid,hSelf);
pFile->tid = hSelf;
- releaseLockInfo(pFile->pLock);
- rc = findLockInfo(pFile->h, &pFile->pLock, 0);
- TRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h,
- locktypeName(pFile->locktype),
- locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
- return rc;
+ if (pFile->pLock != NULL) {
+ releaseLockInfo(pFile->pLock);
+ rc = findLockInfo(pFile->h, &pFile->pLock, 0);
+ TRACE5("LOCK %d is now %s(%s,%d)\n", pFile->h,
+ locktypeName(pFile->locktype),
+ locktypeName(pFile->pLock->locktype), pFile->pLock->cnt);
+ return rc;
+ } else {
+ return SQLITE_OK;
+ }
}
#else
/* On single-threaded builds, ownership transfer is a no-op */
@@ -679,7 +794,12 @@ int sqlite3UnixFileExists(const char *zF
}
/* Forward declaration */
-static int allocateUnixFile(unixFile *pInit, OsFile **pId);
+static int allocateUnixFile(
+ int h, /* File descriptor of the open file */
+ OsFile **pId, /* Write the real file descriptor here */
+ const char *zFilename, /* Name of the file being opened */
+ int delFlag /* If true, make sure the file deletes on close */
+);
/*
** Attempt to open a file for both reading and writing. If that
@@ -699,36 +819,27 @@ int sqlite3UnixOpenReadWrite(
OsFile **pId,
int *pReadonly
){
- int rc;
- unixFile f;
-
+ int h;
+
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadWrite, zFilename, pId, pReadonly);
assert( 0==*pId );
- f.h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
- SQLITE_DEFAULT_FILE_PERMISSIONS);
- if( f.h<0 ){
+ h = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY,
+ SQLITE_DEFAULT_FILE_PERMISSIONS);
+ if( h<0 ){
#ifdef EISDIR
if( errno==EISDIR ){
return SQLITE_CANTOPEN;
}
#endif
- f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
- if( f.h<0 ){
+ h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+ if( h<0 ){
return SQLITE_CANTOPEN;
}
*pReadonly = 1;
}else{
*pReadonly = 0;
}
- sqlite3OsEnterMutex();
- rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
- sqlite3OsLeaveMutex();
- if( rc ){
- close(f.h);
- return SQLITE_NOMEM;
- }
- TRACE3("OPEN %-3d %s\n", f.h, zFilename);
- return allocateUnixFile(&f, pId);
+ return allocateUnixFile(h, pId, zFilename, 0);
}
@@ -747,30 +858,17 @@ int sqlite3UnixOpenExclusive(const char
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3UnixOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
- int rc;
- unixFile f;
+ int h;
CRASH_TEST_OVERRIDE(sqlite3CrashOpenExclusive, zFilename, pId, delFlag);
assert( 0==*pId );
- f.h = open(zFilename,
+ h = open(zFilename,
O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY,
SQLITE_DEFAULT_FILE_PERMISSIONS);
- if( f.h<0 ){
+ if( h<0 ){
return SQLITE_CANTOPEN;
}
- sqlite3OsEnterMutex();
- rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
- sqlite3OsLeaveMutex();
- if( rc ){
- close(f.h);
- unlink(zFilename);
- return SQLITE_NOMEM;
- }
- if( delFlag ){
- unlink(zFilename);
- }
- TRACE3("OPEN-EX %-3d %s\n", f.h, zFilename);
- return allocateUnixFile(&f, pId);
+ return allocateUnixFile(h, pId, zFilename, delFlag);
}
/*
@@ -781,24 +879,15 @@ int sqlite3UnixOpenReadOnly(const char *
** On failure, return SQLITE_CANTOPEN.
*/
int sqlite3UnixOpenReadOnly(const char *zFilename, OsFile **pId){
- int rc;
- unixFile f;
-
+ int h;
+
CRASH_TEST_OVERRIDE(sqlite3CrashOpenReadOnly, zFilename, pId, 0);
assert( 0==*pId );
- f.h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
- if( f.h<0 ){
+ h = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+ if( h<0 ){
return SQLITE_CANTOPEN;
}
- sqlite3OsEnterMutex();
- rc = findLockInfo(f.h, &f.pLock, &f.pOpen);
- sqlite3OsLeaveMutex();
- if( rc ){
- close(f.h);
- return SQLITE_NOMEM;
- }
- TRACE3("OPEN-RO %-3d %s\n", f.h, zFilename);
- return allocateUnixFile(&f, pId);
+ return allocateUnixFile(h, pId, zFilename, 0);
}
/*
@@ -810,6 +899,9 @@ int sqlite3UnixOpenReadOnly(const char *
** This routine is only meaningful for Unix. It is a no-op under
** windows since windows does not support hard links.
**
+** If FULL_FSYNC is enabled, this function is not longer useful,
+** a FULL_FSYNC sync applies to all pending disk operations.
+**
** On success, a handle for a previously open file at *id is
** updated with the new directory file descriptor and SQLITE_OK is
** returned.
@@ -928,18 +1020,20 @@ static int unixRead(OsFile *id, void *pB
static int unixRead(OsFile *id, void *pBuf, int amt){
int got;
assert( id );
- SimulateIOError(SQLITE_IOERR);
TIMER_START;
got = seekAndRead((unixFile*)id, pBuf, amt);
TIMER_END;
TRACE5("READ %-3d %5d %7d %d\n", ((unixFile*)id)->h, got,
last_page, TIMER_ELAPSED);
SEEK(0);
- /* if( got<0 ) got = 0; */
+ SimulateIOError( got = -1 );
if( got==amt ){
return SQLITE_OK;
+ }else if( got<0 ){
+ return SQLITE_IOERR_READ;
}else{
- return SQLITE_IOERR;
+ memset(&((char*)pBuf)[got], 0, amt-got);
+ return SQLITE_IOERR_SHORT_READ;
}
}
@@ -970,8 +1064,6 @@ static int unixWrite(OsFile *id, const v
int wrote = 0;
assert( id );
assert( amt>0 );
- SimulateIOError(SQLITE_IOERR);
- SimulateDiskfullError;
TIMER_START;
while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){
amt -= wrote;
@@ -981,8 +1073,14 @@ static int unixWrite(OsFile *id, const v
TRACE5("WRITE %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote,
last_page, TIMER_ELAPSED);
SEEK(0);
+ SimulateIOError(( wrote=(-1), amt=1 ));
+ SimulateDiskfullError(( wrote=0, amt=1 ));
if( amt>0 ){
- return SQLITE_FULL;
+ if( wrote<0 ){
+ return SQLITE_IOERR_WRITE;
+ }else{
+ return SQLITE_FULL;
+ }
}
return SQLITE_OK;
}
@@ -994,7 +1092,7 @@ static int unixSeek(OsFile *id, i64 offs
assert( id );
SEEK(offset/1024 + 1);
#ifdef SQLITE_TEST
- if( offset ) SimulateDiskfullError
+ if( offset ) SimulateDiskfullError(return SQLITE_FULL);
#endif
((unixFile*)id)->offset = offset;
return SQLITE_OK;
@@ -1062,19 +1160,13 @@ static int full_fsync(int fd, int fullSy
#if HAVE_FULLFSYNC
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 /* if !defined(F_FULLSYNC) */
+ }else
+#endif /* HAVE_FULLFSYNC */
if( dataOnly ){
rc = fdatasync(fd);
}else{
rc = fsync(fd);
}
-#endif /* defined(F_FULLFSYNC) */
#endif /* defined(SQLITE_NO_SYNC) */
return rc;
@@ -1096,12 +1188,14 @@ static int unixSync(OsFile *id, int data
** will not roll back - possibly leading to database corruption.
*/
static int unixSync(OsFile *id, int dataOnly){
+ int rc;
unixFile *pFile = (unixFile*)id;
assert( pFile );
- SimulateIOError(SQLITE_IOERR);
TRACE2("SYNC %-3d\n", pFile->h);
- if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){
- return SQLITE_IOERR;
+ rc = full_fsync(pFile->h, pFile->fullSync, dataOnly);
+ SimulateIOError( rc=1 );
+ if( rc ){
+ return SQLITE_IOERR_FSYNC;
}
if( pFile->dirfd>=0 ){
TRACE4("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
@@ -1141,7 +1235,6 @@ int sqlite3UnixSyncDirectory(const char
#else
int fd;
int r;
- SimulateIOError(SQLITE_IOERR);
fd = open(zDirname, O_RDONLY|O_BINARY, 0);
TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
if( fd<0 ){
@@ -1149,7 +1242,12 @@ int sqlite3UnixSyncDirectory(const char
}
r = fsync(fd);
close(fd);
- return ((r==0)?SQLITE_OK:SQLITE_IOERR);
+ SimulateIOError( r=1 );
+ if( r ){
+ return SQLITE_IOERR_DIR_FSYNC;
+ }else{
+ return SQLITE_OK;
+ }
#endif
}
@@ -1157,20 +1255,28 @@ static int unixTruncate(OsFile *id, i64
** Truncate an open file to a specified size
*/
static int unixTruncate(OsFile *id, i64 nByte){
+ int rc;
assert( id );
- SimulateIOError(SQLITE_IOERR);
- return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
+ rc = ftruncate(((unixFile*)id)->h, nByte);
+ SimulateIOError( rc=1 );
+ if( rc ){
+ return SQLITE_IOERR_TRUNCATE;
+ }else{
+ return SQLITE_OK;
+ }
}
/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(OsFile *id, i64 *pSize){
+ int rc;
struct stat buf;
assert( id );
- SimulateIOError(SQLITE_IOERR);
- if( fstat(((unixFile*)id)->h, &buf)!=0 ){
- return SQLITE_IOERR;
+ rc = fstat(((unixFile*)id)->h, &buf);
+ SimulateIOError( rc=1 );
+ if( rc!=0 ){
+ return SQLITE_IOERR_FSTAT;
}
*pSize = buf.st_size;
return SQLITE_OK;
@@ -1380,7 +1486,7 @@ static int unixLock(OsFile *id, int lock
lock.l_len = 1L;
lock.l_type = F_UNLCK;
if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
- rc = SQLITE_IOERR; /* This should never happen */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
goto end_lock;
}
if( s ){
@@ -1469,7 +1575,7 @@ static int unixUnlock(OsFile *id, int lo
lock.l_len = SHARED_SIZE;
if( fcntl(pFile->h, F_SETLK, &lock)!=0 ){
/* This should never happen */
- rc = SQLITE_IOERR;
+ rc = SQLITE_IOERR_RDLOCK;
}
}
lock.l_type = F_UNLCK;
@@ -1479,7 +1585,7 @@ static int unixUnlock(OsFile *id, int lo
if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
pLock->locktype = SHARED_LOCK;
}else{
- rc = SQLITE_IOERR; /* This should never happen */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
}
}
if( locktype==NO_LOCK ){
@@ -1497,7 +1603,7 @@ static int unixUnlock(OsFile *id, int lo
if( fcntl(pFile->h, F_SETLK, &lock)==0 ){
pLock->locktype = NO_LOCK;
}else{
- rc = SQLITE_IOERR; /* This should never happen */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
}
}
@@ -1567,7 +1673,582 @@ static int unixClose(OsFile **pId){
return SQLITE_OK;
}
+
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#pragma mark AFP Support
+
/*
+ ** The afpLockingContext structure contains all afp lock specific state
+ */
+typedef struct afpLockingContext afpLockingContext;
+struct afpLockingContext {
+ unsigned long long sharedLockByte;
+ char *filePath;
+};
+
+struct ByteRangeLockPB2
+{
+ unsigned long long offset; /* offset to first byte to lock */
+ unsigned long long length; /* nbr of bytes to lock */
+ unsigned long long retRangeStart; /* nbr of 1st byte locked if successful */
+ unsigned char unLockFlag; /* 1 = unlock, 0 = lock */
+ unsigned char startEndFlag; /* 1=rel to end of fork, 0=rel to start */
+ int fd; /* file desc to assoc this lock with */
+};
+
+#define afpfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2)
+
+/* return 0 on success, 1 on failure. To match the behavior of the
+ normal posix file locking (used in unixLock for example), we should
+ provide 'richer' return codes - specifically to differentiate between
+ 'file busy' and 'file system error' results */
+static int _AFPFSSetLock(const char *path, int fd, unsigned long long offset,
+ unsigned long long length, int setLockFlag)
+{
+ struct ByteRangeLockPB2 pb;
+ int err;
+
+ pb.unLockFlag = setLockFlag ? 0 : 1;
+ pb.startEndFlag = 0;
+ pb.offset = offset;
+ pb.length = length;
+ pb.fd = fd;
+ TRACE5("AFPLOCK setting lock %s for %d in range %llx:%llx\n",
+ (setLockFlag?"ON":"OFF"), fd, offset, length);
+ err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0);
+ if ( err==-1 ) {
+ TRACE4("AFPLOCK failed to fsctl() '%s' %d %s\n", path, errno,
+ strerror(errno));
+ return 1; // error
+ } else {
+ return 0;
+ }
+}
+
+/*
+ ** This routine checks if there is a RESERVED lock held on the specified
+ ** file by this or any other process. If such a lock is held, return
+ ** non-zero. If the file is unlocked or holds only SHARED locks, then
+ ** return zero.
+ */
+static int afpUnixCheckReservedLock(OsFile *id){
+ int r = 0;
+ unixFile *pFile = (unixFile*)id;
+
+ assert( pFile );
+ afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+
+ /* Check if a thread in this process holds such a lock */
+ if( pFile->locktype>SHARED_LOCK ){
+ r = 1;
+ }
+
+ /* Otherwise see if some other process holds it.
+ */
+ if ( !r ) {
+ // lock the byte
+ int failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1);
+ if (failed) {
+ /* if we failed to get the lock then someone else must have it */
+ r = 1;
+ } else {
+ /* if we succeeded in taking the reserved lock, unlock it to restore
+ ** the original state */
+ _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0);
+ }
+ }
+ TRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
+
+ return r;
+}
+
+/* AFP-style locking following the behavior of unixLock, see the unixLock
+** function comments for details of lock management. */
+static int afpUnixLock(OsFile *id, int locktype)
+{
+ int rc = SQLITE_OK;
+ unixFile *pFile = (unixFile*)id;
+ afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+ int gotPendingLock = 0;
+
+ assert( pFile );
+ TRACE5("LOCK %d %s was %s pid=%d\n", pFile->h,
+ locktypeName(locktype), locktypeName(pFile->locktype), getpid());
+ /* If there is already a lock of this type or more restrictive on the
+ ** OsFile, do nothing. Don't use the afp_end_lock: exit path, as
+ ** sqlite3OsEnterMutex() hasn't been called yet.
+ */
+ if( pFile->locktype>=locktype ){
+ TRACE3("LOCK %d %s ok (already held)\n", pFile->h,
+ locktypeName(locktype));
+ return SQLITE_OK;
+ }
+
+ /* Make sure the locking sequence is correct
+ */
+ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+ assert( locktype!=PENDING_LOCK );
+ assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
+
+ /* This mutex is needed because pFile->pLock is shared across threads
+ */
+ sqlite3OsEnterMutex();
+
+ /* Make sure the current thread owns the pFile.
+ */
+ rc = transferOwnership(pFile);
+ if( rc!=SQLITE_OK ){
+ sqlite3OsLeaveMutex();
+ return rc;
+ }
+
+ /* A PENDING lock is needed before acquiring a SHARED lock and before
+ ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will
+ ** be released.
+ */
+ if( locktype==SHARED_LOCK
+ || (locktype==EXCLUSIVE_LOCK && pFile->locktypefilePath, pFile->h,
+ PENDING_BYTE, 1, 1);
+ if (failed) {
+ rc = SQLITE_BUSY;
+ goto afp_end_lock;
+ }
+ }
+
+ /* If control gets to this point, then actually go ahead and make
+ ** operating system calls for the specified lock.
+ */
+ if( locktype==SHARED_LOCK ){
+ int lk, failed;
+ int tries = 0;
+
+ /* Now get the read-lock */
+ /* note that the quality of the randomness doesn't matter that much */
+ lk = random();
+ context->sharedLockByte = (lk & 0x7fffffff)%(SHARED_SIZE - 1);
+ failed = _AFPFSSetLock(context->filePath, pFile->h,
+ SHARED_FIRST+context->sharedLockByte, 1, 1);
+
+ /* Drop the temporary PENDING lock */
+ if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)) {
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
+ goto afp_end_lock;
+ }
+
+ if( failed ){
+ rc = SQLITE_BUSY;
+ } else {
+ pFile->locktype = SHARED_LOCK;
+ }
+ }else{
+ /* The request was for a RESERVED or EXCLUSIVE lock. It is
+ ** assumed that there is a SHARED or greater lock on the file
+ ** already.
+ */
+ int failed = 0;
+ assert( 0!=pFile->locktype );
+ if (locktype >= RESERVED_LOCK && pFile->locktype < RESERVED_LOCK) {
+ /* Acquire a RESERVED lock */
+ failed = _AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1,1);
+ }
+ if (!failed && locktype == EXCLUSIVE_LOCK) {
+ /* Acquire an EXCLUSIVE lock */
+
+ /* Remove the shared lock before trying the range. we'll need to
+ ** reestablish the shared lock if we can't get the afpUnixUnlock
+ */
+ if (!_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST +
+ context->sharedLockByte, 1, 0)) {
+ /* now attemmpt to get the exclusive lock range */
+ failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST,
+ SHARED_SIZE, 1);
+ if (failed && _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST +
+ context->sharedLockByte, 1, 1)) {
+ rc = SQLITE_IOERR_RDLOCK; /* this should never happen */
+ }
+ } else {
+ /* */
+ rc = SQLITE_IOERR_UNLOCK; /* this should never happen */
+ }
+ }
+ if( failed && rc == SQLITE_OK){
+ rc = SQLITE_BUSY;
+ }
+ }
+
+ if( rc==SQLITE_OK ){
+ pFile->locktype = locktype;
+ }else if( locktype==EXCLUSIVE_LOCK ){
+ pFile->locktype = PENDING_LOCK;
+ }
+
+afp_end_lock:
+ sqlite3OsLeaveMutex();
+ TRACE4("LOCK %d %s %s\n", pFile->h, locktypeName(locktype),
+ rc==SQLITE_OK ? "ok" : "failed");
+ return rc;
+}
+
+/*
+ ** Lower the locking level on file descriptor pFile to locktype. locktype
+ ** must be either NO_LOCK or SHARED_LOCK.
+ **
+ ** If the locking level of the file descriptor is already at or below
+ ** the requested locking level, this routine is a no-op.
+ */
+static int afpUnixUnlock(OsFile *id, int locktype) {
+ struct flock lock;
+ int rc = SQLITE_OK;
+ unixFile *pFile = (unixFile*)id;
+ afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
+
+ assert( pFile );
+ TRACE5("UNLOCK %d %d was %d pid=%d\n", pFile->h, locktype,
+ pFile->locktype, getpid());
+
+ assert( locktype<=SHARED_LOCK );
+ if( pFile->locktype<=locktype ){
+ return SQLITE_OK;
+ }
+ if( CHECK_THREADID(pFile) ){
+ return SQLITE_MISUSE;
+ }
+ sqlite3OsEnterMutex();
+ if( pFile->locktype>SHARED_LOCK ){
+ if( locktype==SHARED_LOCK ){
+ int failed = 0;
+
+ /* unlock the exclusive range - then re-establish the shared lock */
+ if (pFile->locktype==EXCLUSIVE_LOCK) {
+ failed = _AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST,
+ SHARED_SIZE, 0);
+ if (!failed) {
+ /* successfully removed the exclusive lock */
+ if (_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST+
+ context->sharedLockByte, 1, 1)) {
+ /* failed to re-establish our shared lock */
+ rc = SQLITE_IOERR_RDLOCK; /* This should never happen */
+ }
+ } else {
+ /* This should never happen - failed to unlock the exclusive range */
+ rc = SQLITE_IOERR_UNLOCK;
+ }
+ }
+ }
+ if (rc == SQLITE_OK && pFile->locktype>=PENDING_LOCK) {
+ if (_AFPFSSetLock(context->filePath, pFile->h, PENDING_BYTE, 1, 0)){
+ /* failed to release the pending lock */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
+ }
+ }
+ if (rc == SQLITE_OK && pFile->locktype>=RESERVED_LOCK) {
+ if (_AFPFSSetLock(context->filePath, pFile->h, RESERVED_BYTE, 1, 0)) {
+ /* failed to release the reserved lock */
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
+ }
+ }
+ }
+ if( locktype==NO_LOCK ){
+ int failed = _AFPFSSetLock(context->filePath, pFile->h,
+ SHARED_FIRST + context->sharedLockByte, 1, 0);
+ if (failed) {
+ rc = SQLITE_IOERR_UNLOCK; /* This should never happen */
+ }
+ }
+ if (rc == SQLITE_OK)
+ pFile->locktype = locktype;
+ sqlite3OsLeaveMutex();
+ return rc;
+}
+
+/*
+ ** Close a file & cleanup AFP specific locking context
+ */
+static int afpUnixClose(OsFile **pId) {
+ unixFile *id = (unixFile*)*pId;
+
+ if( !id ) return SQLITE_OK;
+ afpUnixUnlock(*pId, NO_LOCK);
+ /* free the AFP locking structure */
+ if (id->lockingContext != NULL) {
+ if (((afpLockingContext *)id->lockingContext)->filePath != NULL)
+ sqlite3ThreadSafeFree(((afpLockingContext*)id->lockingContext)->filePath);
+ sqlite3ThreadSafeFree(id->lockingContext);
+ }
+
+ if( id->dirfd>=0 ) close(id->dirfd);
+ id->dirfd = -1;
+ close(id->h);
+ id->isOpen = 0;
+ TRACE2("CLOSE %-3d\n", id->h);
+ OpenCounter(-1);
+ sqlite3ThreadSafeFree(id);
+ *pId = 0;
+ return SQLITE_OK;
+}
+
+
+#pragma mark flock() style locking
+
+/*
+ ** The flockLockingContext is not used
+ */
+typedef void flockLockingContext;
+
+static int flockUnixCheckReservedLock(OsFile *id) {
+ unixFile *pFile = (unixFile*)id;
+
+ if (pFile->locktype == RESERVED_LOCK) {
+ return 1; // already have a reserved lock
+ } else {
+ // attempt to get the lock
+ int rc = flock(pFile->h, LOCK_EX | LOCK_NB);
+ if (!rc) {
+ // got the lock, unlock it
+ flock(pFile->h, LOCK_UN);
+ return 0; // no one has it reserved
+ }
+ return 1; // someone else might have it reserved
+ }
+}
+
+static int flockUnixLock(OsFile *id, int locktype) {
+ unixFile *pFile = (unixFile*)id;
+
+ // if we already have a lock, it is exclusive.
+ // Just adjust level and punt on outta here.
+ if (pFile->locktype > NO_LOCK) {
+ pFile->locktype = locktype;
+ return SQLITE_OK;
+ }
+
+ // grab an exclusive lock
+ int rc = flock(pFile->h, LOCK_EX | LOCK_NB);
+ if (rc) {
+ // didn't get, must be busy
+ return SQLITE_BUSY;
+ } else {
+ // got it, set the type and return ok
+ pFile->locktype = locktype;
+ return SQLITE_OK;
+ }
+}
+
+static int flockUnixUnlock(OsFile *id, int locktype) {
+ unixFile *pFile = (unixFile*)id;
+
+ assert( locktype<=SHARED_LOCK );
+
+ // no-op if possible
+ if( pFile->locktype==locktype ){
+ return SQLITE_OK;
+ }
+
+ // shared can just be set because we always have an exclusive
+ if (locktype==SHARED_LOCK) {
+ pFile->locktype = locktype;
+ return SQLITE_OK;
+ }
+
+ // no, really, unlock.
+ int rc = flock(pFile->h, LOCK_UN);
+ if (rc)
+ return SQLITE_IOERR_UNLOCK;
+ else {
+ pFile->locktype = NO_LOCK;
+ return SQLITE_OK;
+ }
+}
+
+/*
+ ** Close a file.
+ */
+static int flockUnixClose(OsFile **pId) {
+ unixFile *id = (unixFile*)*pId;
+
+ if( !id ) return SQLITE_OK;
+ flockUnixUnlock(*pId, NO_LOCK);
+
+ if( id->dirfd>=0 ) close(id->dirfd);
+ id->dirfd = -1;
+ sqlite3OsEnterMutex();
+
+ close(id->h);
+ sqlite3OsLeaveMutex();
+ id->isOpen = 0;
+ TRACE2("CLOSE %-3d\n", id->h);
+ OpenCounter(-1);
+ sqlite3ThreadSafeFree(id);
+ *pId = 0;
+ return SQLITE_OK;
+}
+
+#pragma mark Old-School .lock file based locking
+
+/*
+ ** The dotlockLockingContext structure contains all dotlock (.lock) lock
+ ** specific state
+ */
+typedef struct dotlockLockingContext dotlockLockingContext;
+struct dotlockLockingContext {
+ char *lockPath;
+};
+
+
+static int dotlockUnixCheckReservedLock(OsFile *id) {
+ unixFile *pFile = (unixFile*)id;
+ dotlockLockingContext *context =
+ (dotlockLockingContext *) pFile->lockingContext;
+
+ if (pFile->locktype == RESERVED_LOCK) {
+ return 1; // already have a reserved lock
+ } else {
+ struct stat statBuf;
+ if (lstat(context->lockPath,&statBuf) == 0)
+ // file exists, someone else has the lock
+ return 1;
+ else
+ // file does not exist, we could have it if we want it
+ return 0;
+ }
+}
+
+static int dotlockUnixLock(OsFile *id, int locktype) {
+ unixFile *pFile = (unixFile*)id;
+ dotlockLockingContext *context =
+ (dotlockLockingContext *) pFile->lockingContext;
+
+ // if we already have a lock, it is exclusive.
+ // Just adjust level and punt on outta here.
+ if (pFile->locktype > NO_LOCK) {
+ pFile->locktype = locktype;
+
+ /* Always update the timestamp on the old file */
+ utimes(context->lockPath,NULL);
+ return SQLITE_OK;
+ }
+
+ // check to see if lock file already exists
+ struct stat statBuf;
+ if (lstat(context->lockPath,&statBuf) == 0){
+ return SQLITE_BUSY; // it does, busy
+ }
+
+ // grab an exclusive lock
+ int fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600);
+ if (fd < 0) {
+ // failed to open/create the file, someone else may have stolen the lock
+ return SQLITE_BUSY;
+ }
+ close(fd);
+
+ // got it, set the type and return ok
+ pFile->locktype = locktype;
+ return SQLITE_OK;
+}
+
+static int dotlockUnixUnlock(OsFile *id, int locktype) {
+ unixFile *pFile = (unixFile*)id;
+ dotlockLockingContext *context =
+ (dotlockLockingContext *) pFile->lockingContext;
+
+ assert( locktype<=SHARED_LOCK );
+
+ // no-op if possible
+ if( pFile->locktype==locktype ){
+ return SQLITE_OK;
+ }
+
+ // shared can just be set because we always have an exclusive
+ if (locktype==SHARED_LOCK) {
+ pFile->locktype = locktype;
+ return SQLITE_OK;
+ }
+
+ // no, really, unlock.
+ unlink(context->lockPath);
+ pFile->locktype = NO_LOCK;
+ return SQLITE_OK;
+}
+
+/*
+ ** Close a file.
+ */
+static int dotlockUnixClose(OsFile **pId) {
+ unixFile *id = (unixFile*)*pId;
+
+ if( !id ) return SQLITE_OK;
+ dotlockUnixUnlock(*pId, NO_LOCK);
+ /* free the dotlock locking structure */
+ if (id->lockingContext != NULL) {
+ if (((dotlockLockingContext *)id->lockingContext)->lockPath != NULL)
+ sqlite3ThreadSafeFree( ( (dotlockLockingContext *)
+ id->lockingContext)->lockPath);
+ sqlite3ThreadSafeFree(id->lockingContext);
+ }
+
+ if( id->dirfd>=0 ) close(id->dirfd);
+ id->dirfd = -1;
+ sqlite3OsEnterMutex();
+
+ close(id->h);
+
+ sqlite3OsLeaveMutex();
+ id->isOpen = 0;
+ TRACE2("CLOSE %-3d\n", id->h);
+ OpenCounter(-1);
+ sqlite3ThreadSafeFree(id);
+ *pId = 0;
+ return SQLITE_OK;
+}
+
+
+#pragma mark No locking
+
+/*
+ ** The nolockLockingContext is void
+ */
+typedef void nolockLockingContext;
+
+static int nolockUnixCheckReservedLock(OsFile *id) {
+ return 0;
+}
+
+static int nolockUnixLock(OsFile *id, int locktype) {
+ return SQLITE_OK;
+}
+
+static int nolockUnixUnlock(OsFile *id, int locktype) {
+ return SQLITE_OK;
+}
+
+/*
+ ** Close a file.
+ */
+static int nolockUnixClose(OsFile **pId) {
+ unixFile *id = (unixFile*)*pId;
+
+ if( !id ) return SQLITE_OK;
+ if( id->dirfd>=0 ) close(id->dirfd);
+ id->dirfd = -1;
+ sqlite3OsEnterMutex();
+
+ close(id->h);
+
+ sqlite3OsLeaveMutex();
+ id->isOpen = 0;
+ TRACE2("CLOSE %-3d\n", id->h);
+ OpenCounter(-1);
+ sqlite3ThreadSafeFree(id);
+ *pId = 0;
+ return SQLITE_OK;
+}
+
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
+/*
** Turn a relative pathname into a full pathname. Return a pointer
** to the full pathname stored in space obtained from sqliteMalloc().
** The calling function is responsible for freeing this space once it
@@ -1660,36 +2341,239 @@ static const IoMethod sqlite3UnixIoMetho
unixCheckReservedLock,
};
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
/*
-** Allocate memory for a unixFile. Initialize the new unixFile
-** to the value given in pInit and return a pointer to the new
-** OsFile. If we run out of memory, close the file and return NULL.
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with AFP style file locking.
+ */
+static const IoMethod sqlite3AFPLockingUnixIoMethod = {
+ afpUnixClose,
+ unixOpenDirectory,
+ unixRead,
+ unixWrite,
+ unixSeek,
+ unixTruncate,
+ unixSync,
+ unixSetFullSync,
+ unixFileHandle,
+ unixFileSize,
+ afpUnixLock,
+ afpUnixUnlock,
+ unixLockState,
+ afpUnixCheckReservedLock,
+};
+
+/*
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with flock() style file locking.
+ */
+static const IoMethod sqlite3FlockLockingUnixIoMethod = {
+ flockUnixClose,
+ unixOpenDirectory,
+ unixRead,
+ unixWrite,
+ unixSeek,
+ unixTruncate,
+ unixSync,
+ unixSetFullSync,
+ unixFileHandle,
+ unixFileSize,
+ flockUnixLock,
+ flockUnixUnlock,
+ unixLockState,
+ flockUnixCheckReservedLock,
+};
+
+/*
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with dotlock style file locking.
+ */
+static const IoMethod sqlite3DotlockLockingUnixIoMethod = {
+ dotlockUnixClose,
+ unixOpenDirectory,
+ unixRead,
+ unixWrite,
+ unixSeek,
+ unixTruncate,
+ unixSync,
+ unixSetFullSync,
+ unixFileHandle,
+ unixFileSize,
+ dotlockUnixLock,
+ dotlockUnixUnlock,
+ unixLockState,
+ dotlockUnixCheckReservedLock,
+};
+
+/*
+ ** This vector defines all the methods that can operate on an OsFile
+ ** for unix with dotlock style file locking.
+ */
+static const IoMethod sqlite3NolockLockingUnixIoMethod = {
+ nolockUnixClose,
+ unixOpenDirectory,
+ unixRead,
+ unixWrite,
+ unixSeek,
+ unixTruncate,
+ unixSync,
+ unixSetFullSync,
+ unixFileHandle,
+ unixFileSize,
+ nolockUnixLock,
+ nolockUnixUnlock,
+ unixLockState,
+ nolockUnixCheckReservedLock,
+};
+
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+
+/*
+** Allocate memory for a new unixFile and initialize that unixFile.
+** Write a pointer to the new unixFile into *pId.
+** If we run out of memory, close the file and return an error.
*/
-static int allocateUnixFile(unixFile *pInit, OsFile **pId){
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+/*
+ ** When locking extensions are enabled, the filepath and locking style
+ ** are needed to determine the unixFile pMethod to use for locking operations.
+ ** The locking-style specific lockingContext data structure is created
+ ** and assigned here also.
+ */
+static int allocateUnixFile(
+ int h, /* Open file descriptor of file being opened */
+ OsFile **pId, /* Write completed initialization here */
+ const char *zFilename, /* Name of the file being opened */
+ int delFlag /* Delete-on-or-before-close flag */
+){
+ sqlite3LockingStyle lockingStyle;
unixFile *pNew;
- pInit->dirfd = -1;
- pInit->fullSync = 0;
- pInit->locktype = 0;
- pInit->offset = 0;
- SET_THREADID(pInit);
+ unixFile f;
+ int rc;
+
+ lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
+ if ( lockingStyle == posixLockingStyle ) {
+ sqlite3OsEnterMutex();
+ rc = findLockInfo(h, &f.pLock, &f.pOpen);
+ sqlite3OsLeaveMutex();
+ if( rc ){
+ close(h);
+ unlink(zFilename);
+ return SQLITE_NOMEM;
+ }
+ } else {
+ // pLock and pOpen are only used for posix advisory locking
+ f.pLock = NULL;
+ f.pOpen = NULL;
+ }
+ if( delFlag ){
+ unlink(zFilename);
+ }
+ f.dirfd = -1;
+ f.fullSync = 0;
+ f.locktype = 0;
+ f.offset = 0;
+ f.h = h;
+ SET_THREADID(&f);
pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
if( pNew==0 ){
- close(pInit->h);
+ close(h);
sqlite3OsEnterMutex();
- releaseLockInfo(pInit->pLock);
- releaseOpenCnt(pInit->pOpen);
+ releaseLockInfo(f.pLock);
+ releaseOpenCnt(f.pOpen);
sqlite3OsLeaveMutex();
*pId = 0;
return SQLITE_NOMEM;
}else{
- *pNew = *pInit;
- pNew->pMethod = &sqlite3UnixIoMethod;
+ *pNew = f;
+ switch(lockingStyle) {
+ case afpLockingStyle:
+ /* afp locking uses the file path so it needs to be included in
+ ** the afpLockingContext */
+ pNew->pMethod = &sqlite3AFPLockingUnixIoMethod;
+ pNew->lockingContext =
+ sqlite3ThreadSafeMalloc(sizeof(afpLockingContext));
+ ((afpLockingContext *)pNew->lockingContext)->filePath =
+ sqlite3ThreadSafeMalloc(strlen(zFilename) + 1);
+ strcpy(((afpLockingContext *)pNew->lockingContext)->filePath,
+ zFilename);
+ srandomdev();
+ break;
+ case flockLockingStyle:
+ /* flock locking doesn't need additional lockingContext information */
+ pNew->pMethod = &sqlite3FlockLockingUnixIoMethod;
+ break;
+ case dotlockLockingStyle:
+ /* dotlock locking uses the file path so it needs to be included in
+ ** the dotlockLockingContext */
+ pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod;
+ pNew->lockingContext = sqlite3ThreadSafeMalloc(
+ sizeof(dotlockLockingContext));
+ ((dotlockLockingContext *)pNew->lockingContext)->lockPath =
+ sqlite3ThreadSafeMalloc(strlen(zFilename) + strlen(".lock") + 1);
+ sprintf(((dotlockLockingContext *)pNew->lockingContext)->lockPath,
+ "%s.lock", zFilename);
+ break;
+ case posixLockingStyle:
+ /* posix locking doesn't need additional lockingContext information */
+ pNew->pMethod = &sqlite3UnixIoMethod;
+ break;
+ case noLockingStyle:
+ case unsupportedLockingStyle:
+ default:
+ pNew->pMethod = &sqlite3NolockLockingUnixIoMethod;
+ }
*pId = (OsFile*)pNew;
OpenCounter(+1);
return SQLITE_OK;
}
}
+#else /* SQLITE_ENABLE_LOCKING_STYLE */
+static int allocateUnixFile(
+ int h, /* Open file descriptor on file being opened */
+ OsFile **pId, /* Write the resul unixFile structure here */
+ const char *zFilename, /* Name of the file being opened */
+ int delFlag /* If true, delete the file on or before closing */
+){
+ unixFile *pNew;
+ unixFile f;
+ int rc;
+ sqlite3OsEnterMutex();
+ rc = findLockInfo(h, &f.pLock, &f.pOpen);
+ sqlite3OsLeaveMutex();
+ if( delFlag ){
+ unlink(zFilename);
+ }
+ if( rc ){
+ close(h);
+ return SQLITE_NOMEM;
+ }
+ TRACE3("OPEN %-3d %s\n", h, zFilename);
+ f.dirfd = -1;
+ f.fullSync = 0;
+ f.locktype = 0;
+ f.offset = 0;
+ f.h = h;
+ SET_THREADID(&f);
+ pNew = sqlite3ThreadSafeMalloc( sizeof(unixFile) );
+ if( pNew==0 ){
+ close(h);
+ sqlite3OsEnterMutex();
+ releaseLockInfo(f.pLock);
+ releaseOpenCnt(f.pOpen);
+ sqlite3OsLeaveMutex();
+ *pId = 0;
+ return SQLITE_NOMEM;
+ }else{
+ *pNew = f;
+ pNew->pMethod = &sqlite3UnixIoMethod;
+ *pId = (OsFile*)pNew;
+ OpenCounter(+1);
+ return SQLITE_OK;
+ }
+}
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
#endif /* SQLITE_OMIT_DISKIO */
/***************************************************************************
@@ -1698,7 +2582,24 @@ static int allocateUnixFile(unixFile *pI
****************************************************************************/
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+#include
+void *sqlite3UnixDlopen(const char *zFilename){
+ return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL);
+}
+void *sqlite3UnixDlsym(void *pHandle, const char *zSymbol){
+ return dlsym(pHandle, zSymbol);
+}
+int sqlite3UnixDlclose(void *pHandle){
+ return dlclose(pHandle);
+}
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
+
+/*
** Get information to seed the random number generator. The seed
** is written into the buffer zBuf[256]. The calling function must
** supply a sufficiently large buffer.
============================================================
--- sqlite/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f
+++ sqlite/os_win.c 92df146ed964401969831a19bb490d76ce4de4c0
@@ -124,16 +124,14 @@ int sqlite3_os_type = 0;
#endif /* OS_WINCE */
/*
-** Convert a UTF-8 string to UTF-32. Space to hold the returned string
-** is obtained from sqliteMalloc.
+** Convert a UTF-8 string to microsoft unicode (UTF-16?).
+**
+** Space to hold the returned string is obtained from sqliteMalloc.
*/
static WCHAR *utf8ToUnicode(const char *zFilename){
int nChar;
WCHAR *zWideFilename;
- if( !isNT() ){
- return 0;
- }
nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
zWideFilename = sqliteMalloc( nChar*sizeof(zWideFilename[0]) );
if( zWideFilename==0 ){
@@ -148,7 +146,7 @@ static WCHAR *utf8ToUnicode(const char *
}
/*
-** Convert UTF-32 to UTF-8. Space to hold the returned string is
+** Convert microsoft unicode to UTF-8. Space to hold the returned string is
** obtained from sqliteMalloc().
*/
static char *unicodeToUtf8(const WCHAR *zWideFilename){
@@ -169,6 +167,91 @@ static char *unicodeToUtf8(const WCHAR *
return zFilename;
}
+/*
+** Convert an ansi string to microsoft unicode, based on the
+** current codepage settings for file apis.
+**
+** Space to hold the returned string is obtained
+** from sqliteMalloc.
+*/
+static WCHAR *mbcsToUnicode(const char *zFilename){
+ int nByte;
+ WCHAR *zMbcsFilename;
+ int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+ nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, NULL,0)*sizeof(WCHAR);
+ zMbcsFilename = sqliteMalloc( nByte*sizeof(zMbcsFilename[0]) );
+ if( zMbcsFilename==0 ){
+ return 0;
+ }
+ nByte = MultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename, nByte);
+ if( nByte==0 ){
+ sqliteFree(zMbcsFilename);
+ zMbcsFilename = 0;
+ }
+ return zMbcsFilename;
+}
+
+/*
+** Convert microsoft unicode to multibyte character string, based on the
+** user's Ansi codepage.
+**
+** Space to hold the returned string is obtained from
+** sqliteMalloc().
+*/
+static char *unicodeToMbcs(const WCHAR *zWideFilename){
+ int nByte;
+ char *zFilename;
+ int codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+ nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
+ zFilename = sqliteMalloc( nByte );
+ if( zFilename==0 ){
+ return 0;
+ }
+ nByte = WideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename, nByte,
+ 0, 0);
+ if( nByte == 0 ){
+ sqliteFree(zFilename);
+ zFilename = 0;
+ }
+ return zFilename;
+}
+
+/*
+** Convert multibyte character string to UTF-8. Space to hold the
+** returned string is obtained from sqliteMalloc().
+*/
+static char *mbcsToUtf8(const char *zFilename){
+ char *zFilenameUtf8;
+ WCHAR *zTmpWide;
+
+ zTmpWide = mbcsToUnicode(zFilename);
+ if( zTmpWide==0 ){
+ return 0;
+ }
+ zFilenameUtf8 = unicodeToUtf8(zTmpWide);
+ sqliteFree(zTmpWide);
+ return zFilenameUtf8;
+}
+
+/*
+** Convert UTF-8 to multibyte character string. Space to hold the
+** returned string is obtained from sqliteMalloc().
+*/
+static char *utf8ToMbcs(const char *zFilename){
+ char *zFilenameMbcs;
+ WCHAR *zTmpWide;
+
+ zTmpWide = utf8ToUnicode(zFilename);
+ if( zTmpWide==0 ){
+ return 0;
+ }
+ zFilenameMbcs = unicodeToMbcs(zTmpWide);
+ sqliteFree(zTmpWide);
+ return zFilenameMbcs;
+}
+
#if OS_WINCE
/*************************************************************************
** This section contains code for WinCE only.
@@ -476,6 +559,23 @@ static BOOL winceLockFileEx(
#endif /* OS_WINCE */
/*
+** Convert a UTF-8 filename into whatever form the underlying
+** operating system wants filenames in. Space to hold the result
+** is obtained from sqliteMalloc and must be freed by the calling
+** function.
+*/
+static void *convertUtf8Filename(const char *zFilename){
+ void *zConverted = 0;
+ if( isNT() ){
+ zConverted = utf8ToUnicode(zFilename);
+ }else{
+ zConverted = utf8ToMbcs(zFilename);
+ }
+ /* caller will handle out of memory */
+ return zConverted;
+}
+
+/*
** Delete the named file.
**
** Note that windows does not allow a file to be deleted if some other
@@ -489,25 +589,30 @@ int sqlite3WinDelete(const char *zFilena
*/
#define MX_DELETION_ATTEMPTS 3
int sqlite3WinDelete(const char *zFilename){
- WCHAR *zWide = utf8ToUnicode(zFilename);
int cnt = 0;
int rc;
- if( zWide ){
+ void *zConverted = convertUtf8Filename(zFilename);
+ if( zConverted==0 ){
+ return SQLITE_NOMEM;
+ }
+ if( isNT() ){
do{
- rc = DeleteFileW(zWide);
- }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
- sqliteFree(zWide);
+ rc = DeleteFileW(zConverted);
+ }while( rc==0 && GetFileAttributesW(zConverted)!=0xffffffff
+ && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
}else{
#if OS_WINCE
return SQLITE_NOMEM;
#else
do{
- rc = DeleteFileA(zFilename);
- }while( rc==0 && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
+ rc = DeleteFileA(zConverted);
+ }while( rc==0 && GetFileAttributesA(zConverted)!=0xffffffff
+ && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
#endif
}
+ sqliteFree(zConverted);
TRACE2("DELETE \"%s\"\n", zFilename);
- return rc==0 ? SQLITE_OK : SQLITE_IOERR;
+ return rc!=0 ? SQLITE_OK : SQLITE_IOERR;
}
/*
@@ -515,17 +620,20 @@ int sqlite3WinFileExists(const char *zFi
*/
int sqlite3WinFileExists(const char *zFilename){
int exists = 0;
- WCHAR *zWide = utf8ToUnicode(zFilename);
- if( zWide ){
- exists = GetFileAttributesW(zWide) != 0xffffffff;
- sqliteFree(zWide);
+ void *zConverted = convertUtf8Filename(zFilename);
+ if( zConverted==0 ){
+ return SQLITE_NOMEM;
+ }
+ if( isNT() ){
+ exists = GetFileAttributesW((WCHAR*)zConverted) != 0xffffffff;
}else{
#if OS_WINCE
return SQLITE_NOMEM;
#else
- exists = GetFileAttributesA(zFilename) != 0xffffffff;
+ exists = GetFileAttributesA((char*)zConverted) != 0xffffffff;
#endif
}
+ sqliteFree(zConverted);
return exists;
}
@@ -552,10 +660,14 @@ int sqlite3WinOpenReadWrite(
){
winFile f;
HANDLE h;
- WCHAR *zWide = utf8ToUnicode(zFilename);
+ void *zConverted = convertUtf8Filename(zFilename);
+ if( zConverted==0 ){
+ return SQLITE_NOMEM;
+ }
assert( *pId==0 );
- if( zWide ){
- h = CreateFileW(zWide,
+
+ if( isNT() ){
+ h = CreateFileW((WCHAR*)zConverted,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
@@ -564,7 +676,7 @@ int sqlite3WinOpenReadWrite(
NULL
);
if( h==INVALID_HANDLE_VALUE ){
- h = CreateFileW(zWide,
+ h = CreateFileW((WCHAR*)zConverted,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
@@ -573,7 +685,7 @@ int sqlite3WinOpenReadWrite(
NULL
);
if( h==INVALID_HANDLE_VALUE ){
- sqliteFree(zWide);
+ sqliteFree(zConverted);
return SQLITE_CANTOPEN;
}
*pReadonly = 1;
@@ -583,16 +695,15 @@ int sqlite3WinOpenReadWrite(
#if OS_WINCE
if (!winceCreateLock(zFilename, &f)){
CloseHandle(h);
- sqliteFree(zWide);
+ sqliteFree(zConverted);
return SQLITE_CANTOPEN;
}
#endif
- sqliteFree(zWide);
}else{
#if OS_WINCE
return SQLITE_NOMEM;
#else
- h = CreateFileA(zFilename,
+ h = CreateFileA((char*)zConverted,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
@@ -601,7 +712,7 @@ int sqlite3WinOpenReadWrite(
NULL
);
if( h==INVALID_HANDLE_VALUE ){
- h = CreateFileA(zFilename,
+ h = CreateFileA((char*)zConverted,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
@@ -610,6 +721,7 @@ int sqlite3WinOpenReadWrite(
NULL
);
if( h==INVALID_HANDLE_VALUE ){
+ sqliteFree(zConverted);
return SQLITE_CANTOPEN;
}
*pReadonly = 1;
@@ -618,6 +730,9 @@ int sqlite3WinOpenReadWrite(
}
#endif /* OS_WINCE */
}
+
+ sqliteFree(zConverted);
+
f.h = h;
#if OS_WINCE
f.zDeleteOnClose = 0;
@@ -650,8 +765,11 @@ int sqlite3WinOpenExclusive(const char *
int sqlite3WinOpenExclusive(const char *zFilename, OsFile **pId, int delFlag){
winFile f;
HANDLE h;
- int fileflags;
- WCHAR *zWide = utf8ToUnicode(zFilename);
+ DWORD fileflags;
+ void *zConverted = convertUtf8Filename(zFilename);
+ if( zConverted==0 ){
+ return SQLITE_NOMEM;
+ }
assert( *pId == 0 );
fileflags = FILE_FLAG_RANDOM_ACCESS;
#if !OS_WINCE
@@ -659,10 +777,10 @@ int sqlite3WinOpenExclusive(const char *
fileflags |= FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE;
}
#endif
- if( zWide ){
+ if( isNT() ){
int cnt = 0;
do{
- h = CreateFileW(zWide,
+ h = CreateFileW((WCHAR*)zConverted,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
@@ -671,14 +789,13 @@ int sqlite3WinOpenExclusive(const char *
NULL
);
}while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
- sqliteFree(zWide);
}else{
#if OS_WINCE
return SQLITE_NOMEM;
#else
int cnt = 0;
do{
- h = CreateFileA(zFilename,
+ h = CreateFileA((char*)zConverted,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
@@ -689,14 +806,18 @@ int sqlite3WinOpenExclusive(const char *
}while( h==INVALID_HANDLE_VALUE && cnt++ < 2 && (Sleep(100), 1) );
#endif /* OS_WINCE */
}
+#if OS_WINCE
+ if( delFlag && h!=INVALID_HANDLE_VALUE ){
+ f.zDeleteOnClose = zConverted;
+ zConverted = 0;
+ }
+ f.hMutex = NULL;
+#endif
+ sqliteFree(zConverted);
if( h==INVALID_HANDLE_VALUE ){
return SQLITE_CANTOPEN;
}
f.h = h;
-#if OS_WINCE
- f.zDeleteOnClose = delFlag ? utf8ToUnicode(zFilename) : 0;
- f.hMutex = NULL;
-#endif
TRACE3("OPEN EX %d \"%s\"\n", h, zFilename);
return allocateWinFile(&f, pId);
}
@@ -711,10 +832,13 @@ int sqlite3WinOpenReadOnly(const char *z
int sqlite3WinOpenReadOnly(const char *zFilename, OsFile **pId){
winFile f;
HANDLE h;
- WCHAR *zWide = utf8ToUnicode(zFilename);
+ void *zConverted = convertUtf8Filename(zFilename);
+ if( zConverted==0 ){
+ return SQLITE_NOMEM;
+ }
assert( *pId==0 );
- if( zWide ){
- h = CreateFileW(zWide,
+ if( isNT() ){
+ h = CreateFileW((WCHAR*)zConverted,
GENERIC_READ,
0,
NULL,
@@ -722,12 +846,11 @@ int sqlite3WinOpenReadOnly(const char *z
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
NULL
);
- sqliteFree(zWide);
}else{
#if OS_WINCE
return SQLITE_NOMEM;
#else
- h = CreateFileA(zFilename,
+ h = CreateFileA((char*)zConverted,
GENERIC_READ,
0,
NULL,
@@ -737,6 +860,7 @@ int sqlite3WinOpenReadOnly(const char *z
);
#endif
}
+ sqliteFree(zConverted);
if( h==INVALID_HANDLE_VALUE ){
return SQLITE_CANTOPEN;
}
@@ -802,9 +926,21 @@ int sqlite3WinTempFileName(char *zBuf){
strncpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
sqliteFree(zMulti);
+ }else{
+ return SQLITE_NOMEM;
}
}else{
- GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
+ char *zUtf8;
+ char zMbcsPath[SQLITE_TEMPNAME_SIZE];
+ GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zMbcsPath);
+ zUtf8 = mbcsToUtf8(zMbcsPath);
+ if( zUtf8 ){
+ strncpy(zTempPath, zUtf8, SQLITE_TEMPNAME_SIZE-30);
+ zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
+ sqliteFree(zUtf8);
+ }else{
+ return SQLITE_NOMEM;
+ }
}
for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
zTempPath[i] = 0;
@@ -864,15 +1000,18 @@ static int winRead(OsFile *id, void *pBu
static int winRead(OsFile *id, void *pBuf, int amt){
DWORD got;
assert( id!=0 );
- SimulateIOError(SQLITE_IOERR);
+ SimulateIOError(return SQLITE_IOERR);
TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
- got = 0;
+ got = -1;
}
if( got==(DWORD)amt ){
return SQLITE_OK;
+ }else if( got<0 ){
+ return SQLITE_IOERR_READ;
}else{
- return SQLITE_IOERR;
+ memset(&((char*)pBuf)[got], 0, amt-got);
+ return SQLITE_IOERR_SHORT_READ;
}
}
@@ -884,8 +1023,8 @@ static int winWrite(OsFile *id, const vo
int rc = 0;
DWORD wrote;
assert( id!=0 );
- SimulateIOError(SQLITE_IOERR);
- SimulateDiskfullError;
+ SimulateIOError(return SQLITE_IOERR);
+ SimulateDiskfullError(return SQLITE_FULL);
TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
assert( amt>0 );
while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
@@ -915,7 +1054,7 @@ static int winSeek(OsFile *id, i64 offse
DWORD rc;
assert( id!=0 );
#ifdef SQLITE_TEST
- if( offset ) SimulateDiskfullError
+ if( offset ) SimulateDiskfullError(return SQLITE_FULL);
#endif
SEEK(offset/1024 + 1);
rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
@@ -944,7 +1083,7 @@ int sqlite3WinSyncDirectory(const char *
** than UNIX.
*/
int sqlite3WinSyncDirectory(const char *zDirname){
- SimulateIOError(SQLITE_IOERR);
+ SimulateIOError(return SQLITE_IOERR);
return SQLITE_OK;
}
@@ -955,7 +1094,7 @@ static int winTruncate(OsFile *id, i64 n
LONG upperBits = nByte>>32;
assert( id!=0 );
TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
- SimulateIOError(SQLITE_IOERR);
+ SimulateIOError(return SQLITE_IOERR);
SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
SetEndOfFile(((winFile*)id)->h);
return SQLITE_OK;
@@ -967,7 +1106,7 @@ static int winFileSize(OsFile *id, i64 *
static int winFileSize(OsFile *id, i64 *pSize){
DWORD upperBits, lowerBits;
assert( id!=0 );
- SimulateIOError(SQLITE_IOERR);
+ SimulateIOError(return SQLITE_IOERR);
lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
*pSize = (((i64)upperBits)<<32) + lowerBits;
return SQLITE_OK;
@@ -1022,20 +1161,24 @@ int sqlite3WinIsDirWritable(char *zDirna
*/
int sqlite3WinIsDirWritable(char *zDirname){
int fileAttr;
- WCHAR *zWide;
+ void *zConverted;
if( zDirname==0 ) return 0;
if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
- zWide = utf8ToUnicode(zDirname);
- if( zWide ){
- fileAttr = GetFileAttributesW(zWide);
- sqliteFree(zWide);
+
+ zConverted = convertUtf8Filename(zDirname);
+ if( zConverted==0 ){
+ return SQLITE_NOMEM;
+ }
+ if( isNT() ){
+ fileAttr = GetFileAttributesW((WCHAR*)zConverted);
}else{
#if OS_WINCE
return 0;
#else
- fileAttr = GetFileAttributesA(zDirname);
+ fileAttr = GetFileAttributesA((char*)zConverted);
#endif
}
+ sqliteFree(zConverted);
if( fileAttr == 0xffffffff ) return 0;
if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
return 0;
@@ -1258,24 +1401,33 @@ char *sqlite3WinFullPathname(const char
/* WinCE has no concept of a relative pathname, or so I am told. */
zFull = sqliteStrDup(zRelative);
#else
- char *zNotUsed;
- WCHAR *zWide;
int nByte;
- zWide = utf8ToUnicode(zRelative);
- if( zWide ){
+ void *zConverted;
+ zConverted = convertUtf8Filename(zRelative);
+ if( isNT() ){
WCHAR *zTemp, *zNotUsedW;
- nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
+ nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, &zNotUsedW) + 1;
zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
- if( zTemp==0 ) return 0;
- GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
- sqliteFree(zWide);
+ if( zTemp==0 ){
+ sqliteFree(zConverted);
+ return 0;
+ }
+ GetFullPathNameW((WCHAR*)zConverted, nByte, zTemp, &zNotUsedW);
+ sqliteFree(zConverted);
zFull = unicodeToUtf8(zTemp);
sqliteFree(zTemp);
}else{
- nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
- zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
- if( zFull==0 ) return 0;
- GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
+ char *zTemp, *zNotUsed;
+ nByte = GetFullPathNameA((char*)zConverted, 0, 0, &zNotUsed) + 1;
+ zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
+ if( zTemp==0 ){
+ sqliteFree(zConverted);
+ return 0;
+ }
+ GetFullPathNameA((char*)zConverted, nByte, zTemp, &zNotUsed);
+ sqliteFree(zConverted);
+ zFull = mbcsToUtf8(zTemp);
+ sqliteFree(zTemp);
}
#endif
return zFull;
@@ -1357,7 +1509,46 @@ static int allocateWinFile(winFile *pIni
** with other miscellanous aspects of the operating system interface
****************************************************************************/
+#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
/*
+** Interfaces for opening a shared library, finding entry points
+** within the shared library, and closing the shared library.
+*/
+void *sqlite3WinDlopen(const char *zFilename){
+ HANDLE h;
+ void *zConverted = convertUtf8Filename(zFilename);
+ if( zConverted==0 ){
+ return 0;
+ }
+ if( isNT() ){
+ h = LoadLibraryW((WCHAR*)zConverted);
+ }else{
+#if OS_WINCE
+ return 0;
+#else
+ h = LoadLibraryA((char*)zConverted);
+#endif
+ }
+ sqliteFree(zConverted);
+ return (void*)h;
+
+}
+void *sqlite3WinDlsym(void *pHandle, const char *zSymbol){
+#if OS_WINCE
+ /* The GetProcAddressA() routine is only available on wince. */
+ return GetProcAddressA((HANDLE)pHandle, zSymbol);
+#else
+ /* All other windows platforms expect GetProcAddress() to take
+ ** an Ansi string regardless of the _UNICODE setting */
+ return GetProcAddress((HANDLE)pHandle, zSymbol);
+#endif
+}
+int sqlite3WinDlclose(void *pHandle){
+ return FreeLibrary((HANDLE)pHandle);
+}
+#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
+
+/*
** Get information to seed the random number generator. The seed
** is written into the buffer zBuf[256]. The calling function must
** supply a sufficiently large buffer.
============================================================
--- sqlite/pager.c e51c079b3cad8394898a6c22330150339103700a
+++ sqlite/pager.c 48296c371c44bf43f1c02e221142149797f33072
@@ -18,7 +18,7 @@
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.271 2006/08/08 13:51:43 drh Exp $
+** @(#) $Id: pager.c,v 1.281 2007/01/04 14:58:14 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
@@ -31,6 +31,7 @@
** Macros for troubleshooting. Normally turned off
*/
#if 0
+#define sqlite3DebugPrintf printf
#define TRACE1(X) sqlite3DebugPrintf(X)
#define TRACE2(X,Y) sqlite3DebugPrintf(X,Y)
#define TRACE3(X,Y,Z) sqlite3DebugPrintf(X,Y,Z)
@@ -231,7 +232,6 @@ struct Pager {
u8 fullSync; /* Do extra syncs of the journal for robustness */
u8 full_fsync; /* Use F_FULLFSYNC when available */
u8 state; /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
- u8 errCode; /* One of several kinds of errors */
u8 tempFile; /* zFilename is a temporary file */
u8 readOnly; /* True for a read-only database */
u8 needSync; /* True if an fsync() is needed on the journal */
@@ -239,6 +239,7 @@ struct Pager {
u8 alwaysRollback; /* Disable dont_rollback() for all pages */
u8 memDb; /* True to inhibit all file I/O */
u8 setMaster; /* True if a m-j name has been written to jrnl */
+ int errCode; /* One of several kinds of errors */
int dbSize; /* Number of pages in the file */
int origDbSize; /* dbSize before the current change */
int stmtSize; /* Size of database (in pages) at stmt_begin() */
@@ -350,7 +351,9 @@ static const unsigned char aJournalMagic
/*
** The default size of a disk sector
*/
-#define PAGER_SECTOR_SIZE 512
+#ifndef PAGER_SECTOR_SIZE
+# define PAGER_SECTOR_SIZE 512
+#endif
/*
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
@@ -476,12 +479,13 @@ static int pager_error(Pager *pPager, in
** will immediately return the same error code.
*/
static int pager_error(Pager *pPager, int rc){
+ int rc2 = rc & 0xff;
assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK );
if(
- rc==SQLITE_FULL ||
- rc==SQLITE_IOERR ||
- rc==SQLITE_CORRUPT ||
- rc==SQLITE_PROTOCOL
+ rc2==SQLITE_FULL ||
+ rc2==SQLITE_IOERR ||
+ rc2==SQLITE_CORRUPT ||
+ rc2==SQLITE_PROTOCOL
){
pPager->errCode = rc;
}
@@ -847,6 +851,23 @@ static PgHdr *pager_lookup(Pager *pPager
}
/*
+** Unlock the database file.
+**
+** Once all locks have been removed from the database file, other
+** processes or threads might change the file. So make sure all of
+** our internal cache is invalidated.
+*/
+static void pager_unlock(Pager *pPager){
+ if( !MEMDB ){
+ sqlite3OsUnlock(pPager->fd, NO_LOCK);
+ pPager->dbSize = -1;
+ }
+ pPager->state = PAGER_UNLOCK;
+ assert( pPager->pAll==0 );
+}
+
+
+/*
** Unlock the database and clear the in-memory cache. This routine
** sets the state of the pager back to what it was when it was first
** opened. Any outstanding pages are invalidated and subsequent attempts
@@ -870,11 +891,9 @@ static void pager_reset(Pager *pPager){
if( pPager->state>=PAGER_RESERVED ){
sqlite3pager_rollback(pPager);
}
- sqlite3OsUnlock(pPager->fd, NO_LOCK);
- pPager->state = PAGER_UNLOCK;
- pPager->dbSize = -1;
+ pager_unlock(pPager);
pPager->nRef = 0;
- assert( pPager->journalOpen==0 );
+ assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
}
/*
@@ -926,6 +945,7 @@ static int pager_unwritelock(Pager *pPag
pPager->setMaster = 0;
pPager->needSync = 0;
pPager->pFirstSynced = pPager->pFirst;
+ pPager->dbSize = -1;
return rc;
}
@@ -1340,6 +1360,10 @@ static int pager_playback(Pager *pPager)
pPager->journalOff = szJ;
break;
}else{
+ /* If we are unable to rollback a hot journal, then the database
+ ** is probably not recoverable. Return CORRUPT.
+ */
+ rc = SQLITE_CORRUPT;
goto end_playback;
}
}
@@ -1416,6 +1440,7 @@ static int pager_stmt_playback(Pager *pP
if( pPager->state>=PAGER_EXCLUSIVE ){
rc = pager_truncate(pPager, pPager->stmtSize);
}
+ assert( pPager->state>=PAGER_SHARED );
pPager->dbSize = pPager->stmtSize;
/* Figure out how many records are in the statement journal.
@@ -1793,14 +1818,19 @@ void enable_simulated_io_errors(void){
** response is to zero the memory at pDest and continue. A real IO error
** will presumably recur and be picked up later (Todo: Think about this).
*/
-void sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
+int sqlite3pager_read_fileheader(Pager *pPager, int N, unsigned char *pDest){
+ int rc = SQLITE_OK;
memset(pDest, 0, N);
if( MEMDB==0 ){
disable_simulated_io_errors();
sqlite3OsSeek(pPager->fd, 0);
- sqlite3OsRead(pPager->fd, pDest, N);
enable_simulated_io_errors();
+ rc = sqlite3OsRead(pPager->fd, pDest, N);
+ if( rc==SQLITE_IOERR_SHORT_READ ){
+ rc = SQLITE_OK;
+ }
}
+ return rc;
}
/*
@@ -1814,12 +1844,13 @@ int sqlite3pager_pagecount(Pager *pPager
*/
int sqlite3pager_pagecount(Pager *pPager){
i64 n;
+ int rc;
assert( pPager!=0 );
if( pPager->dbSize>=0 ){
n = pPager->dbSize;
} else {
- if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
- pager_error(pPager, SQLITE_IOERR);
+ if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
+ pager_error(pPager, rc);
return 0;
}
if( n>0 && npageSize ){
@@ -1959,9 +1990,15 @@ static int pager_wait_on_lock(Pager *pPa
*/
static int pager_wait_on_lock(Pager *pPager, int locktype){
int rc;
+
+ /* The OS lock values must be the same as the Pager lock values */
assert( PAGER_SHARED==SHARED_LOCK );
assert( PAGER_RESERVED==RESERVED_LOCK );
assert( PAGER_EXCLUSIVE==EXCLUSIVE_LOCK );
+
+ /* If the file is currently unlocked then the size must be unknown */
+ assert( pPager->state>=PAGER_SHARED || pPager->dbSize<0 || MEMDB );
+
if( pPager->state>=locktype ){
rc = SQLITE_OK;
}else{
@@ -1980,6 +2017,7 @@ int sqlite3pager_truncate(Pager *pPager,
*/
int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
int rc;
+ assert( pPager->state>=PAGER_SHARED || MEMDB );
sqlite3pager_pagecount(pPager);
if( pPager->errCode ){
rc = pPager->errCode;
@@ -2026,7 +2064,6 @@ int sqlite3pager_close(Pager *pPager){
** to the caller.
*/
int sqlite3pager_close(Pager *pPager){
- PgHdr *pPg, *pNext;
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to
** malloc() must have already been made by this thread before it gets
@@ -2038,46 +2075,10 @@ int sqlite3pager_close(Pager *pPager){
assert( pTsd && pTsd->nAlloc );
#endif
- switch( pPager->state ){
- 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.
- */
- disable_simulated_io_errors();
- sqlite3pager_rollback(pPager);
- enable_simulated_io_errors();
- if( !MEMDB ){
- sqlite3OsUnlock(pPager->fd, NO_LOCK);
- }
- assert( pPager->errCode || pPager->journalOpen==0 );
- break;
- }
- case PAGER_SHARED: {
- if( !MEMDB ){
- sqlite3OsUnlock(pPager->fd, NO_LOCK);
- }
- break;
- }
- default: {
- /* Do nothing */
- break;
- }
- }
- for(pPg=pPager->pAll; pPg; pPg=pNext){
-#ifndef NDEBUG
- if( MEMDB ){
- PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
- assert( !pPg->alwaysRollback );
- assert( !pHist->pOrig );
- assert( !pHist->pStmt );
- }
-#endif
- pNext = pPg->pNextAll;
- sqliteFree(pPg);
- }
+ disable_simulated_io_errors();
+ pPager->errCode = 0;
+ pager_reset(pPager);
+ enable_simulated_io_errors();
TRACE2("CLOSE %d\n", PAGERID(pPager));
assert( pPager->errCode || (pPager->journalOpen==0 && pPager->stmtOpen==0) );
if( pPager->journalOpen ){
@@ -2578,7 +2579,7 @@ int sqlite3pager_release_memory(int nReq
** The error will be returned to the user (or users, in the case
** of a shared pager cache) of the pager for which the error occured.
*/
- assert( rc==SQLITE_IOERR || rc==SQLITE_FULL );
+ assert( (rc&0xff)==SQLITE_IOERR || rc==SQLITE_FULL );
assert( p->state>=PAGER_RESERVED );
pager_error(p, rc);
}
@@ -2659,8 +2660,7 @@ int sqlite3pager_get(Pager *pPager, Pgno
*/
rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
if( rc!=SQLITE_OK ){
- sqlite3OsUnlock(pPager->fd, NO_LOCK);
- pPager->state = PAGER_UNLOCK;
+ pager_unlock(pPager);
return pager_error(pPager, rc);
}
pPager->state = PAGER_EXCLUSIVE;
@@ -2675,8 +2675,7 @@ int sqlite3pager_get(Pager *pPager, Pgno
*/
rc = sqlite3OsOpenReadOnly(pPager->zJournal, &pPager->jfd);
if( rc!=SQLITE_OK ){
- sqlite3OsUnlock(pPager->fd, NO_LOCK);
- pPager->state = PAGER_UNLOCK;
+ pager_unlock(pPager);
return SQLITE_BUSY;
}
pPager->journalOpen = 1;
@@ -2783,19 +2782,10 @@ int sqlite3pager_get(Pager *pPager, Pgno
}
TRACE3("FETCH %d page %d\n", PAGERID(pPager), pPg->pgno);
CODEC1(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
- if( rc!=SQLITE_OK ){
- i64 fileSize;
- int rc2 = sqlite3OsFileSize(pPager->fd, &fileSize);
- if( rc2!=SQLITE_OK || fileSize>=pgno*pPager->pageSize ){
- /* An IO error occured in one of the the sqlite3OsSeek() or
- ** sqlite3OsRead() calls above. */
- pPg->pgno = 0;
- sqlite3pager_unref(PGHDR_TO_DATA(pPg));
- return rc;
- }else{
- clear_simulated_io_error();
- memset(PGHDR_TO_DATA(pPg), 0, pPager->pageSize);
- }
+ if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
+ pPg->pgno = 0;
+ sqlite3pager_unref(PGHDR_TO_DATA(pPg));
+ return rc;
}else{
TEST_INCR(pPager->nRead);
}
@@ -2967,8 +2957,7 @@ failed_to_open_journal:
*/
sqlite3OsDelete(pPager->zJournal);
}else{
- sqlite3OsUnlock(pPager->fd, NO_LOCK);
- pPager->state = PAGER_UNLOCK;
+ pager_reset(pPager);
}
return rc;
}
@@ -3227,6 +3216,7 @@ int sqlite3pager_write(void *pData){
/* Update the database size and return.
*/
+ assert( pPager->state>=PAGER_SHARED );
if( pPager->dbSize<(int)pPg->pgno ){
pPager->dbSize = pPg->pgno;
if( !MEMDB && pPager->dbSize==PENDING_BYTE/pPager->pageSize ){
@@ -3302,6 +3292,7 @@ void sqlite3pager_dont_write(Pager *pPag
assert( pPg!=0 ); /* We never call _dont_write unless the page is in mem */
pPg->alwaysRollback = 1;
if( pPg->dirty && !pPager->stmtInUse ){
+ assert( pPager->state>=PAGER_SHARED );
if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSizedbSize ){
/* If this pages is the last page in the file and the file has grown
** during the current transaction, then do NOT mark the page as clean.
@@ -3331,7 +3322,8 @@ void sqlite3pager_dont_rollback(void *pD
PgHdr *pPg = DATA_TO_PGHDR(pData);
Pager *pPager = pPg->pPager;
- if( pPager->state!=PAGER_EXCLUSIVE || pPager->journalOpen==0 ) return;
+ assert( pPager->state>=PAGER_RESERVED );
+ if( pPager->journalOpen==0 ) return;
if( pPg->alwaysRollback || pPager->alwaysRollback || MEMDB ) return;
if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
assert( pPager->aInJournal!=0 );
@@ -3399,14 +3391,12 @@ int sqlite3pager_commit(Pager *pPager){
** if there have been no changes to the database file. */
assert( pPager->needSync==0 );
rc = pager_unwritelock(pPager);
- pPager->dbSize = -1;
return rc;
}
assert( pPager->journalOpen );
rc = sqlite3pager_sync(pPager, 0, 0);
if( rc==SQLITE_OK ){
rc = pager_unwritelock(pPager);
- pPager->dbSize = -1;
}
return rc;
}
@@ -3464,7 +3454,6 @@ int sqlite3pager_rollback(Pager *pPager)
if( !pPager->dirtyCache || !pPager->journalOpen ){
rc = pager_unwritelock(pPager);
- pPager->dbSize = -1;
return rc;
}
@@ -3540,6 +3529,7 @@ int sqlite3pager_stmt_begin(Pager *pPage
int rc;
char zTemp[SQLITE_TEMPNAME_SIZE];
assert( !pPager->stmtInUse );
+ assert( pPager->state>=PAGER_SHARED );
assert( pPager->dbSize>=0 );
TRACE2("STMT-BEGIN %d\n", PAGERID(pPager));
if( MEMDB ){
============================================================
--- sqlite/pager.h 0cff9de5e9019cb695a04d18df8caaaff933a272
+++ sqlite/pager.h 2e6d42f4ae004ae748a037b8468112b851c447a7
@@ -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.51 2006/08/08 13:51:43 drh Exp $
+** @(#) $Id: pager.h,v 1.52 2006/11/06 21:20:26 drh Exp $
*/
#ifndef _PAGER_H_
@@ -75,7 +75,7 @@ int sqlite3pager_set_pagesize(Pager*, in
void sqlite3pager_set_destructor(Pager*, void(*)(void*,int));
void sqlite3pager_set_reiniter(Pager*, void(*)(void*,int));
int sqlite3pager_set_pagesize(Pager*, int);
-void sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
+int sqlite3pager_read_fileheader(Pager*, int, unsigned char*);
void sqlite3pager_set_cachesize(Pager*, int);
int sqlite3pager_close(Pager *pPager);
int sqlite3pager_get(Pager *pPager, Pgno pgno, void **ppPage);
============================================================
--- sqlite/parse.c 74b46eaf63659f557b1b7378a67461e52276c6c1
+++ sqlite/parse.c ce2f4b581ae27ae7b5469855cb3497935f9a3984
@@ -119,8 +119,8 @@ typedef union {
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 581
-#define YYNRULE 309
+#define YYNSTATE 586
+#define YYNRULE 310
#define YYERRORSYMBOL 139
#define YYERRSYMDT yy495
#define YYFALLBACK 1
@@ -176,138 +176,138 @@ static const YYACTIONTYPE yy_action[] =
** yy_default[] Default action for each state.
*/
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 287, 67, 291, 69, 150, 168, 206, 431, 61, 61,
+ /* 0 */ 290, 67, 300, 69, 150, 168, 205, 420, 61, 61,
/* 10 */ 61, 61, 66, 63, 63, 63, 63, 64, 64, 65,
- /* 20 */ 65, 65, 66, 441, 322, 164, 444, 450, 68, 63,
+ /* 20 */ 65, 65, 66, 430, 322, 164, 433, 439, 68, 63,
/* 30 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 64,
- /* 40 */ 64, 65, 65, 65, 66, 60, 58, 295, 454, 455,
- /* 50 */ 451, 451, 62, 62, 61, 61, 61, 61, 513, 63,
- /* 60 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 287,
- /* 70 */ 318, 67, 431, 69, 150, 79, 160, 114, 224, 314,
- /* 80 */ 229, 315, 172, 249, 891, 120, 580, 515, 518, 2,
- /* 90 */ 250, 566, 422, 35, 223, 444, 450, 528, 20, 57,
- /* 100 */ 384, 381, 63, 63, 63, 63, 64, 64, 65, 65,
- /* 110 */ 65, 66, 287, 473, 60, 58, 295, 454, 455, 451,
- /* 120 */ 451, 62, 62, 61, 61, 61, 61, 389, 63, 63,
- /* 130 */ 63, 63, 64, 64, 65, 65, 65, 66, 444, 450,
- /* 140 */ 91, 311, 385, 480, 236, 383, 269, 204, 2, 83,
- /* 150 */ 581, 384, 381, 470, 196, 439, 209, 60, 58, 295,
- /* 160 */ 454, 455, 451, 451, 62, 62, 61, 61, 61, 61,
+ /* 40 */ 64, 65, 65, 65, 66, 60, 58, 296, 443, 444,
+ /* 50 */ 440, 440, 62, 62, 61, 61, 61, 61, 487, 63,
+ /* 60 */ 63, 63, 63, 64, 64, 65, 65, 65, 66, 290,
+ /* 70 */ 318, 67, 420, 69, 150, 79, 160, 114, 240, 341,
+ /* 80 */ 245, 342, 172, 249, 897, 120, 585, 190, 522, 2,
+ /* 90 */ 250, 571, 411, 35, 223, 433, 439, 532, 20, 57,
+ /* 100 */ 388, 385, 63, 63, 63, 63, 64, 64, 65, 65,
+ /* 110 */ 65, 66, 290, 489, 60, 58, 296, 443, 444, 440,
+ /* 120 */ 440, 62, 62, 61, 61, 61, 61, 393, 63, 63,
+ /* 130 */ 63, 63, 64, 64, 65, 65, 65, 66, 433, 439,
+ /* 140 */ 91, 314, 389, 473, 230, 529, 504, 204, 168, 55,
+ /* 150 */ 420, 197, 528, 407, 196, 428, 208, 60, 58, 296,
+ /* 160 */ 443, 444, 440, 440, 62, 62, 61, 61, 61, 61,
/* 170 */ 170, 63, 63, 63, 63, 64, 64, 65, 65, 65,
- /* 180 */ 66, 287, 486, 439, 209, 132, 109, 270, 423, 443,
- /* 190 */ 402, 281, 390, 391, 441, 517, 164, 318, 507, 67,
- /* 200 */ 526, 69, 150, 562, 423, 143, 516, 444, 450, 145,
- /* 210 */ 146, 578, 882, 373, 882, 511, 171, 156, 514, 422,
- /* 220 */ 40, 337, 426, 19, 287, 140, 60, 58, 295, 454,
- /* 230 */ 455, 451, 451, 62, 62, 61, 61, 61, 61, 380,
+ /* 180 */ 66, 290, 479, 428, 208, 412, 109, 81, 412, 432,
+ /* 190 */ 406, 284, 394, 395, 430, 521, 164, 318, 517, 67,
+ /* 200 */ 530, 69, 150, 567, 412, 492, 493, 433, 439, 145,
+ /* 210 */ 146, 583, 888, 376, 888, 420, 171, 156, 488, 411,
+ /* 220 */ 40, 337, 415, 19, 290, 140, 60, 58, 296, 443,
+ /* 230 */ 444, 440, 440, 62, 62, 61, 61, 61, 61, 384,
/* 240 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66,
- /* 250 */ 444, 450, 575, 404, 405, 428, 428, 428, 329, 332,
- /* 260 */ 240, 545, 67, 468, 69, 150, 271, 287, 291, 60,
- /* 270 */ 58, 295, 454, 455, 451, 451, 62, 62, 61, 61,
- /* 280 */ 61, 61, 124, 63, 63, 63, 63, 64, 64, 65,
- /* 290 */ 65, 65, 66, 444, 450, 401, 510, 389, 290, 544,
- /* 300 */ 65, 65, 65, 66, 507, 389, 542, 405, 443, 294,
- /* 310 */ 434, 435, 60, 58, 295, 454, 455, 451, 451, 62,
- /* 320 */ 62, 61, 61, 61, 61, 206, 63, 63, 63, 63,
- /* 330 */ 64, 64, 65, 65, 65, 66, 519, 514, 366, 287,
- /* 340 */ 75, 426, 148, 490, 224, 314, 229, 315, 172, 249,
- /* 350 */ 367, 265, 264, 1, 574, 286, 250, 389, 416, 445,
- /* 360 */ 446, 206, 390, 391, 177, 444, 450, 340, 343, 344,
- /* 370 */ 390, 391, 208, 357, 428, 428, 428, 360, 168, 345,
- /* 380 */ 431, 448, 449, 78, 60, 58, 295, 454, 455, 451,
- /* 390 */ 451, 62, 62, 61, 61, 61, 61, 476, 63, 63,
- /* 400 */ 63, 63, 64, 64, 65, 65, 65, 66, 287, 447,
- /* 410 */ 177, 561, 493, 340, 343, 344, 21, 318, 518, 318,
- /* 420 */ 431, 318, 390, 391, 318, 345, 475, 400, 20, 563,
- /* 430 */ 564, 489, 151, 177, 444, 450, 340, 343, 344, 422,
- /* 440 */ 34, 422, 34, 422, 34, 431, 422, 34, 345, 192,
- /* 450 */ 237, 147, 527, 60, 58, 295, 454, 455, 451, 451,
- /* 460 */ 62, 62, 61, 61, 61, 61, 423, 63, 63, 63,
- /* 470 */ 63, 64, 64, 65, 65, 65, 66, 287, 230, 348,
- /* 480 */ 408, 512, 298, 423, 334, 431, 318, 206, 318, 296,
- /* 490 */ 318, 208, 409, 154, 465, 9, 465, 458, 464, 389,
- /* 500 */ 374, 465, 173, 444, 450, 410, 173, 406, 422, 40,
- /* 510 */ 422, 48, 422, 48, 321, 434, 435, 407, 324, 475,
- /* 520 */ 457, 457, 60, 58, 295, 454, 455, 451, 451, 62,
- /* 530 */ 62, 61, 61, 61, 61, 459, 63, 63, 63, 63,
- /* 540 */ 64, 64, 65, 65, 65, 66, 287, 318, 499, 238,
- /* 550 */ 253, 480, 389, 338, 408, 149, 421, 306, 289, 307,
- /* 560 */ 420, 389, 289, 389, 390, 391, 409, 250, 500, 422,
- /* 570 */ 27, 155, 444, 450, 431, 422, 3, 208, 539, 410,
- /* 580 */ 335, 328, 578, 881, 324, 881, 457, 457, 484, 423,
- /* 590 */ 242, 60, 58, 295, 454, 455, 451, 451, 62, 62,
- /* 600 */ 61, 61, 61, 61, 255, 63, 63, 63, 63, 64,
- /* 610 */ 64, 65, 65, 65, 66, 287, 368, 390, 391, 488,
- /* 620 */ 90, 299, 324, 575, 457, 457, 390, 391, 390, 391,
- /* 630 */ 318, 525, 494, 318, 392, 393, 394, 518, 524, 431,
- /* 640 */ 241, 444, 450, 183, 477, 181, 571, 20, 324, 297,
- /* 650 */ 457, 457, 422, 28, 541, 422, 23, 505, 287, 339,
- /* 660 */ 60, 58, 295, 454, 455, 451, 451, 62, 62, 61,
- /* 670 */ 61, 61, 61, 318, 63, 63, 63, 63, 64, 64,
- /* 680 */ 65, 65, 65, 66, 444, 450, 421, 535, 354, 535,
- /* 690 */ 420, 259, 300, 505, 816, 422, 32, 74, 505, 76,
- /* 700 */ 188, 287, 505, 60, 58, 295, 454, 455, 451, 451,
+ /* 250 */ 433, 439, 580, 546, 493, 417, 417, 417, 549, 332,
+ /* 260 */ 234, 67, 460, 69, 150, 583, 887, 290, 887, 60,
+ /* 270 */ 58, 296, 443, 444, 440, 440, 62, 62, 61, 61,
+ /* 280 */ 61, 61, 318, 63, 63, 63, 63, 64, 64, 65,
+ /* 290 */ 65, 65, 66, 433, 439, 177, 548, 393, 343, 346,
+ /* 300 */ 347, 515, 490, 271, 411, 40, 580, 473, 432, 224,
+ /* 310 */ 348, 408, 60, 58, 296, 443, 444, 440, 440, 62,
+ /* 320 */ 62, 61, 61, 61, 61, 523, 63, 63, 63, 63,
+ /* 330 */ 64, 64, 65, 65, 65, 66, 303, 488, 300, 290,
+ /* 340 */ 75, 415, 274, 483, 272, 232, 236, 370, 267, 266,
+ /* 350 */ 318, 65, 65, 65, 66, 173, 393, 148, 205, 434,
+ /* 360 */ 435, 231, 394, 395, 177, 433, 439, 343, 346, 347,
+ /* 370 */ 293, 515, 411, 34, 417, 417, 417, 378, 477, 348,
+ /* 380 */ 248, 437, 438, 78, 60, 58, 296, 443, 444, 440,
+ /* 390 */ 440, 62, 62, 61, 61, 61, 61, 205, 63, 63,
+ /* 400 */ 63, 63, 64, 64, 65, 65, 65, 66, 290, 436,
+ /* 410 */ 377, 292, 486, 114, 240, 341, 245, 342, 172, 249,
+ /* 420 */ 318, 394, 395, 273, 318, 177, 250, 456, 343, 346,
+ /* 430 */ 347, 329, 151, 566, 433, 439, 295, 423, 424, 298,
+ /* 440 */ 348, 387, 411, 34, 2, 360, 411, 34, 469, 363,
+ /* 450 */ 247, 568, 569, 60, 58, 296, 443, 444, 440, 440,
+ /* 460 */ 62, 62, 61, 61, 61, 61, 412, 63, 63, 63,
+ /* 470 */ 63, 64, 64, 65, 65, 65, 66, 290, 522, 155,
+ /* 480 */ 515, 503, 21, 452, 318, 299, 420, 404, 20, 297,
+ /* 490 */ 321, 423, 424, 482, 318, 453, 318, 457, 1, 207,
+ /* 500 */ 335, 457, 393, 433, 439, 9, 411, 34, 454, 393,
+ /* 510 */ 494, 147, 531, 207, 543, 216, 411, 48, 411, 48,
+ /* 520 */ 495, 393, 60, 58, 296, 443, 444, 440, 440, 62,
+ /* 530 */ 62, 61, 61, 61, 61, 351, 63, 63, 63, 63,
+ /* 540 */ 64, 64, 65, 65, 65, 66, 290, 318, 447, 334,
+ /* 550 */ 253, 420, 371, 207, 452, 149, 448, 579, 289, 248,
+ /* 560 */ 393, 457, 173, 309, 235, 310, 453, 394, 395, 411,
+ /* 570 */ 27, 420, 433, 439, 394, 395, 405, 520, 367, 454,
+ /* 580 */ 324, 328, 446, 446, 509, 517, 394, 395, 473, 412,
+ /* 590 */ 545, 60, 58, 296, 443, 444, 440, 440, 62, 62,
+ /* 600 */ 61, 61, 61, 61, 510, 63, 63, 63, 63, 64,
+ /* 610 */ 64, 65, 65, 65, 66, 290, 192, 338, 292, 324,
+ /* 620 */ 90, 446, 446, 250, 522, 394, 395, 238, 319, 393,
+ /* 630 */ 822, 477, 318, 576, 20, 324, 420, 446, 446, 411,
+ /* 640 */ 3, 433, 439, 324, 217, 446, 446, 586, 388, 385,
+ /* 650 */ 412, 515, 470, 515, 411, 28, 515, 302, 290, 581,
+ /* 660 */ 60, 58, 296, 443, 444, 440, 440, 62, 62, 61,
+ /* 670 */ 61, 61, 61, 219, 63, 63, 63, 63, 64, 64,
+ /* 680 */ 65, 65, 65, 66, 433, 439, 304, 481, 305, 167,
+ /* 690 */ 156, 307, 358, 392, 394, 395, 396, 397, 398, 582,
+ /* 700 */ 188, 290, 339, 60, 58, 296, 443, 444, 440, 440,
/* 710 */ 62, 62, 61, 61, 61, 61, 318, 63, 63, 63,
- /* 720 */ 63, 64, 64, 65, 65, 65, 66, 444, 450, 174,
- /* 730 */ 175, 176, 377, 216, 423, 480, 248, 301, 422, 53,
- /* 740 */ 505, 505, 259, 259, 287, 259, 60, 70, 295, 454,
- /* 750 */ 455, 451, 451, 62, 62, 61, 61, 61, 61, 365,
+ /* 720 */ 63, 64, 64, 65, 65, 65, 66, 433, 439, 410,
+ /* 730 */ 248, 261, 248, 409, 412, 248, 367, 255, 411, 23,
+ /* 740 */ 539, 357, 539, 261, 290, 261, 60, 70, 296, 443,
+ /* 750 */ 444, 440, 440, 62, 62, 61, 61, 61, 61, 368,
/* 760 */ 63, 63, 63, 63, 64, 64, 65, 65, 65, 66,
- /* 770 */ 444, 450, 247, 319, 244, 302, 304, 248, 167, 156,
- /* 780 */ 361, 248, 379, 260, 552, 259, 554, 287, 259, 219,
- /* 790 */ 58, 295, 454, 455, 451, 451, 62, 62, 61, 61,
- /* 800 */ 61, 61, 318, 63, 63, 63, 63, 64, 64, 65,
- /* 810 */ 65, 65, 66, 444, 450, 484, 432, 484, 22, 248,
- /* 820 */ 248, 207, 388, 364, 422, 24, 555, 364, 54, 556,
- /* 830 */ 309, 119, 437, 437, 295, 454, 455, 451, 451, 62,
- /* 840 */ 62, 61, 61, 61, 61, 318, 63, 63, 63, 63,
+ /* 770 */ 433, 439, 381, 541, 115, 261, 259, 540, 257, 261,
+ /* 780 */ 364, 174, 175, 176, 262, 261, 556, 290, 5, 359,
+ /* 790 */ 58, 296, 443, 444, 440, 440, 62, 62, 61, 61,
+ /* 800 */ 61, 61, 218, 63, 63, 63, 63, 64, 64, 65,
+ /* 810 */ 65, 65, 66, 433, 439, 477, 558, 205, 466, 468,
+ /* 820 */ 559, 206, 383, 261, 261, 261, 560, 152, 54, 467,
+ /* 830 */ 369, 312, 119, 124, 296, 443, 444, 440, 440, 62,
+ /* 840 */ 62, 61, 61, 61, 61, 416, 63, 63, 63, 63,
/* 850 */ 64, 64, 65, 65, 65, 66, 71, 325, 318, 4,
- /* 860 */ 318, 537, 318, 293, 259, 536, 259, 422, 51, 318,
- /* 870 */ 161, 320, 71, 325, 318, 4, 355, 356, 305, 293,
- /* 880 */ 422, 96, 422, 93, 422, 98, 225, 320, 327, 217,
- /* 890 */ 115, 422, 99, 218, 190, 318, 422, 110, 226, 443,
- /* 900 */ 318, 259, 318, 417, 327, 272, 427, 372, 318, 5,
- /* 910 */ 418, 318, 413, 414, 330, 443, 318, 422, 111, 73,
- /* 920 */ 72, 197, 422, 16, 422, 97, 152, 71, 316, 317,
- /* 930 */ 422, 33, 426, 422, 94, 73, 72, 487, 422, 52,
- /* 940 */ 318, 200, 274, 71, 316, 317, 71, 325, 426, 4,
- /* 950 */ 318, 206, 318, 293, 318, 423, 463, 318, 12, 179,
- /* 960 */ 423, 320, 422, 112, 615, 428, 428, 428, 429, 430,
- /* 970 */ 11, 323, 422, 113, 422, 25, 422, 36, 327, 422,
- /* 980 */ 37, 428, 428, 428, 429, 430, 11, 498, 497, 443,
- /* 990 */ 158, 18, 318, 423, 81, 220, 221, 222, 101, 182,
- /* 1000 */ 482, 318, 169, 318, 491, 318, 12, 318, 440, 73,
- /* 1010 */ 72, 202, 466, 276, 422, 26, 474, 71, 316, 317,
- /* 1020 */ 277, 318, 426, 422, 38, 422, 39, 422, 41, 422,
- /* 1030 */ 42, 318, 199, 423, 544, 503, 252, 124, 124, 198,
- /* 1040 */ 318, 479, 201, 422, 43, 318, 483, 452, 318, 246,
- /* 1050 */ 347, 318, 124, 422, 29, 428, 428, 428, 429, 430,
- /* 1060 */ 11, 495, 422, 30, 496, 576, 318, 422, 44, 501,
- /* 1070 */ 422, 45, 318, 422, 46, 520, 318, 533, 534, 318,
- /* 1080 */ 540, 318, 124, 502, 185, 371, 273, 264, 422, 47,
- /* 1090 */ 254, 288, 256, 257, 422, 31, 206, 258, 422, 10,
- /* 1100 */ 352, 422, 49, 422, 50, 577, 548, 549, 169, 88,
- /* 1110 */ 559, 263, 88, 359, 362, 573, 363, 285, 266, 267,
- /* 1120 */ 376, 268, 551, 560, 275, 375, 278, 279, 231, 570,
- /* 1130 */ 227, 142, 398, 326, 469, 436, 438, 472, 494, 159,
- /* 1140 */ 504, 547, 506, 558, 387, 395, 342, 396, 397, 8,
- /* 1150 */ 312, 313, 292, 416, 81, 403, 333, 232, 411, 80,
- /* 1160 */ 228, 331, 419, 415, 56, 77, 210, 412, 239, 166,
- /* 1170 */ 467, 211, 470, 471, 121, 82, 102, 336, 349, 282,
- /* 1180 */ 508, 424, 521, 522, 529, 523, 351, 180, 233, 509,
- /* 1190 */ 234, 184, 235, 283, 531, 425, 353, 85, 186, 117,
- /* 1200 */ 358, 128, 369, 370, 308, 567, 568, 243, 543, 481,
- /* 1210 */ 245, 212, 485, 189, 386, 569, 572, 129, 95, 214,
- /* 1220 */ 215, 399, 550, 116, 130, 205, 55, 616, 131, 617,
- /* 1230 */ 162, 163, 433, 134, 59, 213, 442, 557, 137, 100,
- /* 1240 */ 138, 139, 453, 456, 460, 153, 165, 461, 261, 462,
- /* 1250 */ 6, 122, 13, 12, 7, 532, 478, 123, 157, 492,
- /* 1260 */ 103, 341, 89, 251, 104, 84, 105, 346, 226, 178,
- /* 1270 */ 350, 141, 530, 125, 303, 169, 262, 187, 106, 126,
- /* 1280 */ 538, 284, 546, 127, 191, 14, 194, 92, 17, 86,
- /* 1290 */ 87, 193, 195, 133, 108, 553, 135, 565, 136, 15,
- /* 1300 */ 107, 203, 378, 280, 144, 382, 558, 118, 579, 558,
- /* 1310 */ 558, 310,
+ /* 860 */ 318, 412, 318, 294, 275, 375, 277, 318, 74, 318,
+ /* 870 */ 76, 320, 71, 325, 318, 4, 308, 498, 499, 294,
+ /* 880 */ 411, 32, 411, 53, 411, 24, 154, 320, 327, 411,
+ /* 890 */ 51, 411, 96, 161, 410, 318, 411, 93, 409, 432,
+ /* 900 */ 318, 421, 318, 22, 327, 426, 426, 179, 318, 501,
+ /* 910 */ 143, 318, 468, 508, 507, 432, 318, 411, 98, 73,
+ /* 920 */ 72, 182, 411, 99, 411, 110, 323, 71, 316, 317,
+ /* 930 */ 411, 111, 415, 411, 16, 73, 72, 480, 411, 97,
+ /* 940 */ 318, 412, 330, 71, 316, 317, 71, 325, 415, 4,
+ /* 950 */ 318, 205, 318, 294, 318, 412, 455, 318, 12, 537,
+ /* 960 */ 538, 320, 411, 33, 462, 417, 417, 417, 418, 419,
+ /* 970 */ 11, 463, 411, 94, 411, 52, 411, 112, 327, 411,
+ /* 980 */ 113, 417, 417, 417, 418, 419, 11, 620, 241, 432,
+ /* 990 */ 158, 475, 318, 169, 429, 220, 221, 222, 101, 458,
+ /* 1000 */ 242, 318, 441, 318, 484, 318, 12, 318, 472, 73,
+ /* 1010 */ 72, 202, 476, 279, 411, 25, 246, 71, 316, 317,
+ /* 1020 */ 280, 318, 415, 411, 36, 411, 37, 411, 26, 411,
+ /* 1030 */ 38, 318, 199, 505, 548, 513, 252, 124, 124, 198,
+ /* 1040 */ 318, 506, 201, 411, 39, 318, 511, 350, 318, 124,
+ /* 1050 */ 544, 318, 124, 411, 41, 417, 417, 417, 418, 419,
+ /* 1060 */ 11, 512, 411, 42, 524, 254, 318, 411, 43, 200,
+ /* 1070 */ 411, 29, 318, 411, 30, 552, 318, 169, 553, 318,
+ /* 1080 */ 88, 318, 256, 318, 185, 374, 276, 266, 411, 44,
+ /* 1090 */ 258, 291, 318, 260, 411, 45, 205, 265, 411, 46,
+ /* 1100 */ 318, 411, 47, 411, 31, 411, 10, 563, 578, 88,
+ /* 1110 */ 288, 355, 362, 365, 411, 49, 366, 268, 269, 18,
+ /* 1120 */ 380, 270, 411, 50, 555, 565, 278, 379, 281, 282,
+ /* 1130 */ 575, 142, 225, 402, 425, 427, 326, 504, 551, 461,
+ /* 1140 */ 465, 562, 159, 391, 399, 243, 400, 514, 516, 401,
+ /* 1150 */ 8, 413, 226, 315, 81, 333, 227, 80, 331, 228,
+ /* 1160 */ 345, 229, 77, 56, 209, 166, 459, 233, 210, 407,
+ /* 1170 */ 464, 121, 82, 336, 340, 491, 496, 301, 244, 501,
+ /* 1180 */ 497, 500, 502, 102, 518, 519, 414, 285, 352, 525,
+ /* 1190 */ 180, 526, 527, 533, 237, 181, 474, 239, 354, 478,
+ /* 1200 */ 211, 286, 184, 214, 535, 183, 215, 356, 85, 361,
+ /* 1210 */ 117, 186, 128, 547, 189, 372, 554, 373, 311, 561,
+ /* 1220 */ 572, 129, 130, 131, 138, 573, 95, 132, 577, 263,
+ /* 1230 */ 137, 134, 574, 390, 403, 621, 536, 213, 622, 100,
+ /* 1240 */ 162, 59, 163, 422, 431, 442, 445, 139, 89, 449,
+ /* 1250 */ 153, 165, 6, 450, 451, 122, 471, 13, 7, 92,
+ /* 1260 */ 123, 12, 485, 157, 212, 108, 83, 103, 104, 116,
+ /* 1270 */ 344, 251, 84, 105, 349, 17, 178, 353, 242, 534,
+ /* 1280 */ 141, 125, 306, 187, 106, 169, 126, 287, 542, 264,
+ /* 1290 */ 118, 550, 127, 191, 313, 14, 86, 193, 194, 135,
+ /* 1300 */ 557, 195, 133, 564, 136, 15, 107, 570, 382, 283,
+ /* 1310 */ 144, 203, 386, 87, 584,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 16, 218, 16, 220, 221, 21, 111, 23, 70, 71,
@@ -318,267 +318,267 @@ static const YYCODETYPE yy_lookahead[] =
/* 50 */ 66, 67, 68, 69, 70, 71, 72, 73, 170, 75,
/* 60 */ 76, 77, 78, 79, 80, 81, 82, 83, 84, 16,
/* 70 */ 148, 218, 88, 220, 221, 22, 90, 91, 92, 93,
- /* 80 */ 94, 95, 96, 97, 140, 141, 142, 170, 148, 145,
+ /* 80 */ 94, 95, 96, 97, 140, 141, 142, 22, 148, 145,
/* 90 */ 104, 238, 170, 171, 154, 42, 43, 157, 158, 46,
/* 100 */ 1, 2, 75, 76, 77, 78, 79, 80, 81, 82,
- /* 110 */ 83, 84, 16, 22, 61, 62, 63, 64, 65, 66,
+ /* 110 */ 83, 84, 16, 170, 61, 62, 63, 64, 65, 66,
/* 120 */ 67, 68, 69, 70, 71, 72, 73, 23, 75, 76,
/* 130 */ 77, 78, 79, 80, 81, 82, 83, 84, 42, 43,
- /* 140 */ 44, 143, 144, 162, 222, 142, 14, 149, 145, 19,
- /* 150 */ 0, 1, 2, 23, 156, 79, 80, 61, 62, 63,
+ /* 140 */ 44, 143, 144, 162, 222, 177, 178, 149, 21, 19,
+ /* 150 */ 23, 156, 184, 23, 156, 79, 80, 61, 62, 63,
/* 160 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
/* 170 */ 156, 75, 76, 77, 78, 79, 80, 81, 82, 83,
- /* 180 */ 84, 16, 201, 79, 80, 53, 21, 55, 190, 59,
+ /* 180 */ 84, 16, 201, 79, 80, 190, 21, 122, 190, 59,
/* 190 */ 169, 159, 88, 89, 162, 163, 164, 148, 177, 218,
- /* 200 */ 182, 220, 221, 99, 190, 114, 161, 42, 43, 79,
- /* 210 */ 80, 19, 20, 215, 22, 170, 202, 203, 88, 170,
+ /* 200 */ 182, 220, 221, 99, 190, 186, 187, 42, 43, 79,
+ /* 210 */ 80, 19, 20, 215, 22, 88, 202, 203, 88, 170,
/* 220 */ 171, 207, 92, 19, 16, 21, 61, 62, 63, 64,
/* 230 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 241,
/* 240 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- /* 250 */ 42, 43, 60, 186, 187, 125, 126, 127, 187, 210,
- /* 260 */ 211, 11, 218, 219, 220, 221, 134, 16, 16, 61,
+ /* 250 */ 42, 43, 60, 186, 187, 125, 126, 127, 11, 210,
+ /* 260 */ 211, 218, 219, 220, 221, 19, 20, 16, 22, 61,
/* 270 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- /* 280 */ 72, 73, 22, 75, 76, 77, 78, 79, 80, 81,
- /* 290 */ 82, 83, 84, 42, 43, 168, 169, 23, 151, 49,
- /* 300 */ 81, 82, 83, 84, 177, 23, 186, 187, 59, 165,
- /* 310 */ 166, 167, 61, 62, 63, 64, 65, 66, 67, 68,
- /* 320 */ 69, 70, 71, 72, 73, 111, 75, 76, 77, 78,
- /* 330 */ 79, 80, 81, 82, 83, 84, 182, 88, 124, 16,
- /* 340 */ 132, 92, 22, 20, 92, 93, 94, 95, 96, 97,
- /* 350 */ 100, 101, 102, 19, 244, 245, 104, 23, 98, 42,
- /* 360 */ 43, 111, 88, 89, 90, 42, 43, 93, 94, 95,
- /* 370 */ 88, 89, 228, 226, 125, 126, 127, 230, 21, 105,
- /* 380 */ 23, 64, 65, 132, 61, 62, 63, 64, 65, 66,
- /* 390 */ 67, 68, 69, 70, 71, 72, 73, 115, 75, 76,
+ /* 280 */ 72, 73, 148, 75, 76, 77, 78, 79, 80, 81,
+ /* 290 */ 82, 83, 84, 42, 43, 90, 49, 23, 93, 94,
+ /* 300 */ 95, 148, 161, 14, 170, 171, 60, 162, 59, 191,
+ /* 310 */ 105, 170, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 320 */ 69, 70, 71, 72, 73, 182, 75, 76, 77, 78,
+ /* 330 */ 79, 80, 81, 82, 83, 84, 183, 88, 16, 16,
+ /* 340 */ 132, 92, 53, 20, 55, 211, 201, 100, 101, 102,
+ /* 350 */ 148, 81, 82, 83, 84, 43, 23, 22, 111, 42,
+ /* 360 */ 43, 148, 88, 89, 90, 42, 43, 93, 94, 95,
+ /* 370 */ 151, 148, 170, 171, 125, 126, 127, 91, 148, 105,
+ /* 380 */ 227, 64, 65, 132, 61, 62, 63, 64, 65, 66,
+ /* 390 */ 67, 68, 69, 70, 71, 72, 73, 111, 75, 76,
/* 400 */ 77, 78, 79, 80, 81, 82, 83, 84, 16, 92,
- /* 410 */ 90, 148, 20, 93, 94, 95, 19, 148, 148, 148,
- /* 420 */ 23, 148, 88, 89, 148, 105, 22, 157, 158, 166,
- /* 430 */ 167, 20, 156, 90, 42, 43, 93, 94, 95, 170,
- /* 440 */ 171, 170, 171, 170, 171, 88, 170, 171, 105, 156,
- /* 450 */ 148, 181, 182, 61, 62, 63, 64, 65, 66, 67,
+ /* 410 */ 124, 99, 20, 91, 92, 93, 94, 95, 96, 97,
+ /* 420 */ 148, 88, 89, 134, 148, 90, 104, 225, 93, 94,
+ /* 430 */ 95, 187, 156, 148, 42, 43, 165, 166, 167, 209,
+ /* 440 */ 105, 142, 170, 171, 145, 226, 170, 171, 115, 230,
+ /* 450 */ 227, 166, 167, 61, 62, 63, 64, 65, 66, 67,
/* 460 */ 68, 69, 70, 71, 72, 73, 190, 75, 76, 77,
- /* 470 */ 78, 79, 80, 81, 82, 83, 84, 16, 191, 16,
- /* 480 */ 12, 20, 213, 190, 213, 88, 148, 111, 148, 213,
- /* 490 */ 148, 228, 24, 89, 225, 19, 225, 20, 225, 23,
- /* 500 */ 124, 225, 43, 42, 43, 37, 43, 39, 170, 171,
- /* 510 */ 170, 171, 170, 171, 165, 166, 167, 49, 107, 115,
- /* 520 */ 109, 110, 61, 62, 63, 64, 65, 66, 67, 68,
- /* 530 */ 69, 70, 71, 72, 73, 20, 75, 76, 77, 78,
- /* 540 */ 79, 80, 81, 82, 83, 84, 16, 148, 30, 211,
- /* 550 */ 20, 162, 23, 148, 12, 156, 108, 217, 99, 217,
- /* 560 */ 112, 23, 99, 23, 88, 89, 24, 104, 50, 170,
- /* 570 */ 171, 148, 42, 43, 23, 170, 171, 228, 18, 37,
- /* 580 */ 148, 39, 19, 20, 107, 22, 109, 110, 148, 190,
- /* 590 */ 201, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- /* 600 */ 70, 71, 72, 73, 14, 75, 76, 77, 78, 79,
- /* 610 */ 80, 81, 82, 83, 84, 16, 56, 88, 89, 81,
- /* 620 */ 21, 103, 107, 60, 109, 110, 88, 89, 88, 89,
- /* 630 */ 148, 177, 178, 148, 7, 8, 9, 148, 184, 88,
- /* 640 */ 148, 42, 43, 53, 115, 55, 157, 158, 107, 209,
- /* 650 */ 109, 110, 170, 171, 94, 170, 171, 148, 16, 81,
+ /* 470 */ 78, 79, 80, 81, 82, 83, 84, 16, 148, 148,
+ /* 480 */ 148, 20, 19, 12, 148, 213, 23, 157, 158, 213,
+ /* 490 */ 165, 166, 167, 20, 148, 24, 148, 225, 19, 228,
+ /* 500 */ 148, 225, 23, 42, 43, 19, 170, 171, 37, 23,
+ /* 510 */ 39, 181, 182, 228, 18, 183, 170, 171, 170, 171,
+ /* 520 */ 49, 23, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 530 */ 69, 70, 71, 72, 73, 16, 75, 76, 77, 78,
+ /* 540 */ 79, 80, 81, 82, 83, 84, 16, 148, 20, 213,
+ /* 550 */ 20, 88, 56, 228, 12, 156, 20, 244, 245, 227,
+ /* 560 */ 23, 225, 43, 217, 148, 217, 24, 88, 89, 170,
+ /* 570 */ 171, 23, 42, 43, 88, 89, 168, 169, 148, 37,
+ /* 580 */ 107, 39, 109, 110, 30, 177, 88, 89, 162, 190,
+ /* 590 */ 94, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ /* 600 */ 70, 71, 72, 73, 50, 75, 76, 77, 78, 79,
+ /* 610 */ 80, 81, 82, 83, 84, 16, 156, 148, 99, 107,
+ /* 620 */ 21, 109, 110, 104, 148, 88, 89, 201, 148, 23,
+ /* 630 */ 134, 148, 148, 157, 158, 107, 88, 109, 110, 170,
+ /* 640 */ 171, 42, 43, 107, 214, 109, 110, 0, 1, 2,
+ /* 650 */ 190, 148, 115, 148, 170, 171, 148, 103, 16, 20,
/* 660 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- /* 670 */ 71, 72, 73, 148, 75, 76, 77, 78, 79, 80,
- /* 680 */ 81, 82, 83, 84, 42, 43, 108, 100, 101, 102,
- /* 690 */ 112, 148, 183, 148, 134, 170, 171, 131, 148, 133,
- /* 700 */ 156, 16, 148, 61, 62, 63, 64, 65, 66, 67,
+ /* 670 */ 71, 72, 73, 146, 75, 76, 77, 78, 79, 80,
+ /* 680 */ 81, 82, 83, 84, 42, 43, 183, 81, 183, 202,
+ /* 690 */ 203, 183, 209, 148, 88, 89, 7, 8, 9, 60,
+ /* 700 */ 156, 16, 81, 61, 62, 63, 64, 65, 66, 67,
/* 710 */ 68, 69, 70, 71, 72, 73, 148, 75, 76, 77,
- /* 720 */ 78, 79, 80, 81, 82, 83, 84, 42, 43, 100,
- /* 730 */ 101, 102, 189, 183, 190, 162, 227, 183, 170, 171,
- /* 740 */ 148, 148, 148, 148, 16, 148, 61, 62, 63, 64,
+ /* 720 */ 78, 79, 80, 81, 82, 83, 84, 42, 43, 108,
+ /* 730 */ 227, 148, 227, 112, 190, 227, 148, 14, 170, 171,
+ /* 740 */ 100, 101, 102, 148, 16, 148, 61, 62, 63, 64,
/* 750 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 215,
/* 760 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- /* 770 */ 42, 43, 227, 148, 201, 183, 183, 227, 202, 203,
- /* 780 */ 236, 227, 239, 189, 189, 148, 189, 16, 148, 146,
+ /* 770 */ 42, 43, 189, 25, 148, 148, 53, 29, 55, 148,
+ /* 780 */ 236, 100, 101, 102, 189, 148, 189, 16, 192, 41,
/* 790 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- /* 800 */ 72, 73, 148, 75, 76, 77, 78, 79, 80, 81,
- /* 810 */ 82, 83, 84, 42, 43, 148, 20, 148, 22, 227,
- /* 820 */ 227, 193, 148, 148, 170, 171, 189, 148, 200, 189,
- /* 830 */ 242, 243, 125, 126, 63, 64, 65, 66, 67, 68,
+ /* 800 */ 72, 73, 214, 75, 76, 77, 78, 79, 80, 81,
+ /* 810 */ 82, 83, 84, 42, 43, 148, 189, 111, 22, 22,
+ /* 820 */ 189, 193, 239, 148, 148, 148, 189, 156, 200, 204,
+ /* 830 */ 124, 242, 243, 22, 63, 64, 65, 66, 67, 68,
/* 840 */ 69, 70, 71, 72, 73, 148, 75, 76, 77, 78,
/* 850 */ 79, 80, 81, 82, 83, 84, 16, 17, 148, 19,
- /* 860 */ 148, 25, 148, 23, 148, 29, 148, 170, 171, 148,
- /* 870 */ 19, 31, 16, 17, 148, 19, 209, 41, 209, 23,
- /* 880 */ 170, 171, 170, 171, 170, 171, 92, 31, 48, 214,
- /* 890 */ 148, 170, 171, 214, 22, 148, 170, 171, 104, 59,
- /* 900 */ 148, 148, 148, 27, 48, 189, 148, 189, 148, 192,
- /* 910 */ 34, 148, 7, 8, 148, 59, 148, 170, 171, 79,
- /* 920 */ 80, 156, 170, 171, 170, 171, 156, 87, 88, 89,
+ /* 860 */ 148, 190, 148, 23, 189, 189, 189, 148, 131, 148,
+ /* 870 */ 133, 31, 16, 17, 148, 19, 209, 7, 8, 23,
+ /* 880 */ 170, 171, 170, 171, 170, 171, 89, 31, 48, 170,
+ /* 890 */ 171, 170, 171, 19, 108, 148, 170, 171, 112, 59,
+ /* 900 */ 148, 20, 148, 22, 48, 125, 126, 156, 148, 98,
+ /* 910 */ 114, 148, 115, 91, 92, 59, 148, 170, 171, 79,
+ /* 920 */ 80, 156, 170, 171, 170, 171, 16, 87, 88, 89,
/* 930 */ 170, 171, 92, 170, 171, 79, 80, 81, 170, 171,
- /* 940 */ 148, 19, 189, 87, 88, 89, 16, 17, 92, 19,
- /* 950 */ 148, 111, 148, 23, 148, 190, 20, 148, 22, 156,
- /* 960 */ 190, 31, 170, 171, 113, 125, 126, 127, 128, 129,
- /* 970 */ 130, 16, 170, 171, 170, 171, 170, 171, 48, 170,
- /* 980 */ 171, 125, 126, 127, 128, 129, 130, 91, 92, 59,
- /* 990 */ 5, 69, 148, 190, 122, 10, 11, 12, 13, 156,
- /* 1000 */ 20, 148, 22, 148, 20, 148, 22, 148, 162, 79,
- /* 1010 */ 80, 26, 148, 28, 170, 171, 204, 87, 88, 89,
+ /* 940 */ 148, 190, 148, 87, 88, 89, 16, 17, 92, 19,
+ /* 950 */ 148, 111, 148, 23, 148, 190, 20, 148, 22, 51,
+ /* 960 */ 52, 31, 170, 171, 27, 125, 126, 127, 128, 129,
+ /* 970 */ 130, 34, 170, 171, 170, 171, 170, 171, 48, 170,
+ /* 980 */ 171, 125, 126, 127, 128, 129, 130, 113, 92, 59,
+ /* 990 */ 5, 20, 148, 22, 162, 10, 11, 12, 13, 148,
+ /* 1000 */ 104, 148, 92, 148, 20, 148, 22, 148, 148, 79,
+ /* 1010 */ 80, 26, 148, 28, 170, 171, 148, 87, 88, 89,
/* 1020 */ 35, 148, 92, 170, 171, 170, 171, 170, 171, 170,
- /* 1030 */ 171, 148, 47, 190, 49, 20, 20, 22, 22, 54,
- /* 1040 */ 148, 148, 57, 170, 171, 148, 148, 92, 148, 148,
+ /* 1030 */ 171, 148, 47, 148, 49, 20, 20, 22, 22, 54,
+ /* 1040 */ 148, 179, 57, 170, 171, 148, 179, 20, 148, 22,
/* 1050 */ 20, 148, 22, 170, 171, 125, 126, 127, 128, 129,
- /* 1060 */ 130, 148, 170, 171, 179, 20, 148, 170, 171, 179,
- /* 1070 */ 170, 171, 148, 170, 171, 148, 148, 51, 52, 148,
- /* 1080 */ 20, 148, 22, 179, 232, 100, 101, 102, 170, 171,
+ /* 1060 */ 130, 179, 170, 171, 148, 148, 148, 170, 171, 19,
+ /* 1070 */ 170, 171, 148, 170, 171, 20, 148, 22, 20, 148,
+ /* 1080 */ 22, 148, 148, 148, 232, 100, 101, 102, 170, 171,
/* 1090 */ 148, 106, 148, 148, 170, 171, 111, 148, 170, 171,
- /* 1100 */ 233, 170, 171, 170, 171, 60, 20, 20, 22, 22,
- /* 1110 */ 20, 148, 22, 148, 148, 20, 148, 22, 148, 148,
- /* 1120 */ 135, 148, 148, 148, 148, 148, 148, 148, 194, 148,
- /* 1130 */ 173, 192, 150, 224, 173, 229, 229, 173, 178, 6,
- /* 1140 */ 173, 195, 173, 195, 147, 147, 174, 147, 147, 22,
- /* 1150 */ 155, 99, 40, 98, 122, 172, 119, 195, 172, 120,
- /* 1160 */ 172, 117, 172, 174, 121, 131, 223, 180, 97, 113,
- /* 1170 */ 153, 212, 23, 161, 153, 99, 19, 116, 15, 175,
- /* 1180 */ 161, 190, 172, 172, 153, 172, 153, 152, 196, 180,
- /* 1190 */ 197, 153, 198, 175, 153, 199, 38, 131, 152, 61,
- /* 1200 */ 153, 19, 153, 15, 153, 33, 153, 205, 185, 206,
- /* 1210 */ 205, 212, 206, 185, 1, 153, 138, 188, 160, 212,
- /* 1220 */ 212, 20, 195, 32, 188, 44, 19, 113, 188, 113,
- /* 1230 */ 113, 113, 20, 185, 19, 176, 20, 195, 216, 176,
- /* 1240 */ 216, 19, 92, 108, 11, 19, 22, 20, 234, 20,
- /* 1250 */ 118, 19, 22, 22, 118, 235, 115, 20, 113, 20,
- /* 1260 */ 19, 44, 237, 20, 19, 19, 19, 44, 104, 96,
- /* 1270 */ 16, 21, 17, 99, 36, 22, 134, 99, 19, 45,
- /* 1280 */ 45, 5, 1, 103, 123, 19, 14, 237, 231, 69,
- /* 1290 */ 69, 114, 116, 114, 240, 17, 103, 20, 123, 19,
- /* 1300 */ 14, 136, 58, 137, 19, 3, 247, 243, 4, 247,
- /* 1310 */ 247, 246,
+ /* 1100 */ 148, 170, 171, 170, 171, 170, 171, 20, 20, 22,
+ /* 1110 */ 22, 233, 148, 148, 170, 171, 148, 148, 148, 69,
+ /* 1120 */ 135, 148, 170, 171, 148, 148, 148, 148, 148, 148,
+ /* 1130 */ 148, 192, 194, 150, 229, 229, 224, 178, 195, 173,
+ /* 1140 */ 173, 195, 6, 147, 147, 173, 147, 173, 173, 147,
+ /* 1150 */ 22, 190, 195, 155, 122, 119, 196, 120, 117, 197,
+ /* 1160 */ 174, 198, 131, 121, 223, 113, 153, 97, 212, 23,
+ /* 1170 */ 161, 153, 99, 116, 99, 172, 172, 40, 172, 98,
+ /* 1180 */ 180, 174, 172, 19, 161, 180, 199, 175, 15, 172,
+ /* 1190 */ 152, 172, 172, 153, 205, 152, 206, 205, 153, 206,
+ /* 1200 */ 212, 175, 153, 212, 153, 152, 212, 38, 131, 153,
+ /* 1210 */ 61, 152, 19, 185, 185, 153, 195, 15, 153, 195,
+ /* 1220 */ 33, 188, 188, 188, 216, 153, 160, 188, 138, 234,
+ /* 1230 */ 216, 185, 153, 1, 20, 113, 235, 176, 113, 176,
+ /* 1240 */ 113, 19, 113, 20, 20, 92, 108, 19, 237, 11,
+ /* 1250 */ 19, 22, 118, 20, 20, 19, 115, 22, 118, 237,
+ /* 1260 */ 20, 22, 20, 113, 44, 240, 19, 19, 19, 32,
+ /* 1270 */ 44, 20, 19, 19, 44, 231, 96, 16, 104, 17,
+ /* 1280 */ 21, 99, 36, 99, 19, 22, 45, 5, 45, 134,
+ /* 1290 */ 243, 1, 103, 123, 246, 19, 69, 114, 14, 103,
+ /* 1300 */ 17, 116, 114, 124, 123, 19, 14, 20, 58, 137,
+ /* 1310 */ 19, 136, 3, 69, 4,
};
#define YY_SHIFT_USE_DFLT (-106)
-#define YY_SHIFT_MAX 382
+#define YY_SHIFT_MAX 386
static const short yy_shift_ofst[] = {
/* 0 */ 99, 840, 985, -16, 840, 930, 930, 930, 274, -105,
- /* 10 */ 96, 930, 930, 930, 930, 930, -46, 250, 104, 540,
- /* 20 */ 551, 76, 76, 53, 165, 208, 251, 323, 392, 461,
+ /* 10 */ 96, 930, 930, 930, 930, 930, -46, 247, 104, 498,
+ /* 20 */ 548, 76, 76, 53, 165, 208, 251, 323, 392, 461,
/* 30 */ 530, 599, 642, 685, 642, 642, 642, 642, 642, 642,
/* 40 */ 642, 642, 642, 642, 642, 642, 642, 642, 642, 642,
/* 50 */ 642, 728, 771, 771, 856, 930, 930, 930, 930, 930,
/* 60 */ 930, 930, 930, 930, 930, 930, 930, 930, 930, 930,
/* 70 */ 930, 930, 930, 930, 930, 930, 930, 930, 930, 930,
/* 80 */ 930, 930, 930, 930, 930, 930, 930, 930, 930, 930,
- /* 90 */ 930, 930, 930, -62, -62, -14, 27, 27, -40, 219,
- /* 100 */ 463, 560, 540, 540, 540, 540, 540, 540, 540, 551,
- /* 110 */ -72, -106, -106, -106, 130, 252, 468, 468, 192, 563,
- /* 120 */ 150, 357, 540, 357, 540, 540, 540, 540, 540, 540,
- /* 130 */ 540, 540, 540, 540, 540, 540, 540, 214, 376, -105,
- /* 140 */ -105, -105, -106, -106, -106, 249, 249, 320, 343, 411,
- /* 150 */ 334, 477, 515, 542, 282, 529, 476, 538, 627, 540,
- /* 160 */ 540, 578, 540, 540, 397, 540, 540, 404, 540, 540,
- /* 170 */ 541, 404, 540, 540, 518, 518, 518, 540, 540, 541,
- /* 180 */ 540, 540, 541, 540, 836, 587, 540, 540, 541, 540,
- /* 190 */ 540, 540, 541, 540, 540, 540, 541, 541, 540, 540,
- /* 200 */ 540, 540, 540, 540, 204, 876, 448, 91, 707, 707,
- /* 210 */ 566, 876, 876, 459, 876, 876, 260, 872, 872, 1133,
- /* 220 */ 1133, 1133, 1133, 1127, 1052, 1052, 1112, 1052, 1055, 1052,
- /* 230 */ -105, 1032, 1037, 1039, 1044, 1043, 1034, 1056, 1071, 1149,
- /* 240 */ 1071, 1056, 1076, 1061, 1076, 1061, 1157, 1071, 1071, 1149,
- /* 250 */ 1112, 1052, 1052, 1052, 1157, 1163, 1056, 1056, 1056, 1056,
- /* 260 */ 1158, 1066, 1163, 1056, 1138, 1138, 1182, 1032, 1056, 1188,
- /* 270 */ 1188, 1188, 1032, 1138, 1182, 1056, 1172, 1172, 1056, 1056,
- /* 280 */ 1078, -106, -106, -106, -106, -106, -106, 317, 132, 629,
- /* 290 */ 590, 794, 905, 851, 796, 955, 936, 980, 984, 896,
- /* 300 */ 1015, 1016, 1030, 1026, 1060, 1086, 1087, 1090, 922, 1095,
- /* 310 */ 1045, 1213, 1201, 1191, 1181, 1207, 1114, 1116, 1117, 1118,
- /* 320 */ 1215, 1212, 1216, 1150, 1135, 1222, 1233, 1226, 1227, 1224,
- /* 330 */ 1229, 1132, 1230, 1136, 1231, 1141, 1232, 1237, 1145, 1239,
- /* 340 */ 1217, 1241, 1243, 1245, 1246, 1223, 1247, 1173, 1164, 1254,
- /* 350 */ 1255, 1250, 1174, 1238, 1234, 1253, 1235, 1142, 1178, 1259,
- /* 360 */ 1276, 1281, 1180, 1220, 1221, 1161, 1266, 1177, 1272, 1176,
- /* 370 */ 1278, 1179, 1193, 1175, 1280, 1277, 1286, 1244, 1165, 1166,
- /* 380 */ 1285, 1302, 1304,
+ /* 90 */ 930, 930, 930, -62, -62, -14, 27, 27, -40, 270,
+ /* 100 */ 519, 496, 498, 498, 498, 498, 498, 498, 498, 548,
+ /* 110 */ -72, -106, -106, -106, 130, 322, 471, 471, 192, 246,
+ /* 120 */ 647, 127, 498, 127, 498, 498, 498, 498, 498, 498,
+ /* 130 */ 498, 498, 498, 498, 498, 498, 498, 286, 706, -105,
+ /* 140 */ -105, -105, -106, -106, -106, 249, 249, 335, 205, 473,
+ /* 150 */ 479, 528, 536, 542, 333, 537, 486, 606, 689, 498,
+ /* 160 */ 498, 621, 498, 498, 463, 498, 498, 797, 498, 498,
+ /* 170 */ 512, 797, 498, 498, 554, 554, 554, 498, 498, 512,
+ /* 180 */ 498, 498, 512, 498, 748, 640, 498, 498, 512, 498,
+ /* 190 */ 498, 498, 512, 498, 498, 498, 512, 512, 498, 498,
+ /* 200 */ 498, 498, 498, 498, 204, 786, 796, 780, 780, 737,
+ /* 210 */ 937, 937, 937, 312, 937, 937, 811, 65, 65, 1136,
+ /* 220 */ 1136, 1136, 1136, 1128, -105, 1032, 1036, 1037, 1041, 1042,
+ /* 230 */ 1031, 1052, 1070, 1146, 1070, 1052, 1073, 1057, 1073, 1057,
+ /* 240 */ 1075, 1075, 1137, 1075, 1081, 1075, 1164, 1070, 1070, 1146,
+ /* 250 */ 1137, 1075, 1075, 1075, 1164, 1173, 1052, 1173, 1052, 1173,
+ /* 260 */ 1052, 1052, 1169, 1077, 1173, 1052, 1149, 1149, 1193, 1032,
+ /* 270 */ 1052, 1202, 1202, 1202, 1202, 1032, 1149, 1193, 1052, 1187,
+ /* 280 */ 1187, 1052, 1052, 1090, -106, -106, -106, -106, -106, -106,
+ /* 290 */ 317, 289, 681, 723, 874, 881, 910, 936, 971, 984,
+ /* 300 */ 896, 870, 822, 1015, 1016, 1027, 908, 1030, 1055, 1058,
+ /* 310 */ 1087, 1050, 1088, 639, 1232, 1214, 1122, 1125, 1127, 1129,
+ /* 320 */ 1222, 1223, 1224, 1153, 1138, 1228, 1238, 1231, 1233, 1229,
+ /* 330 */ 1234, 1134, 1235, 1140, 1239, 1141, 1236, 1240, 1150, 1242,
+ /* 340 */ 1237, 1220, 1247, 1226, 1248, 1251, 1249, 1253, 1230, 1254,
+ /* 350 */ 1180, 1174, 1261, 1262, 1259, 1182, 1246, 1241, 1263, 1243,
+ /* 360 */ 1155, 1184, 1265, 1282, 1290, 1189, 1227, 1244, 1170, 1276,
+ /* 370 */ 1183, 1284, 1185, 1283, 1188, 1196, 1181, 1286, 1179, 1287,
+ /* 380 */ 1292, 1250, 1175, 1172, 1291, 1309, 1310,
};
#define YY_REDUCE_USE_DFLT (-218)
-#define YY_REDUCE_MAX 286
+#define YY_REDUCE_MAX 289
static const short yy_reduce_ofst[] = {
- /* 0 */ -56, 276, -2, -19, 399, 269, 49, 271, 270, 14,
- /* 10 */ -147, -78, 273, 338, 340, 342, 44, 544, 263, -60,
- /* 20 */ 32, 144, 349, -217, -217, -217, -217, -217, -217, -217,
+ /* 0 */ -56, 276, -2, -19, 399, 272, 49, 336, 330, 14,
+ /* 10 */ -147, -78, 202, 134, 346, 348, 43, 544, 285, -60,
+ /* 20 */ 32, 271, 325, -217, -217, -217, -217, -217, -217, -217,
/* 30 */ -217, -217, -217, -217, -217, -217, -217, -217, -217, -217,
/* 40 */ -217, -217, -217, -217, -217, -217, -217, -217, -217, -217,
- /* 50 */ -217, -217, -217, -217, 405, 482, 485, 525, 568, 654,
- /* 60 */ 697, 710, 712, 714, 721, 726, 747, 752, 754, 760,
- /* 70 */ 763, 768, 792, 802, 804, 806, 809, 844, 853, 855,
- /* 80 */ 857, 859, 873, 883, 892, 897, 900, 903, 918, 924,
- /* 90 */ 928, 931, 933, -217, -217, 127, -217, -217, -217, -217,
- /* 100 */ 454, 147, 509, 550, 554, 592, 593, 543, 489, -139,
- /* 110 */ -217, -217, -217, -217, 45, 21, 67, 120, 110, 110,
- /* 120 */ 3, 389, 440, 573, 545, 594, 667, 675, 669, 595,
- /* 130 */ 597, 637, 640, 716, 718, 679, 753, 293, 765, 770,
- /* 140 */ 803, 843, 628, 576, 588, -112, -83, 18, 154, 287,
- /* 150 */ 302, 287, 287, 71, 423, 432, 492, 625, 643, 674,
- /* 160 */ 742, 717, 625, 758, 846, 766, 864, 812, 893, 898,
- /* 170 */ 287, 812, 901, 913, 885, 890, 904, 927, 942, 287,
- /* 180 */ 944, 945, 287, 949, 852, 867, 963, 965, 287, 966,
- /* 190 */ 968, 970, 287, 971, 973, 974, 287, 287, 975, 976,
- /* 200 */ 977, 978, 979, 981, 982, 957, 939, 934, 906, 907,
- /* 210 */ 909, 961, 964, 960, 967, 969, 972, 946, 948, 997,
- /* 220 */ 998, 1000, 1001, 995, 983, 986, 987, 988, 989, 990,
- /* 230 */ 991, 962, 992, 993, 994, 996, 943, 1017, 959, 1012,
- /* 240 */ 999, 1021, 1002, 1003, 1005, 1006, 1004, 1007, 1008, 1019,
- /* 250 */ 1009, 1010, 1011, 1013, 1018, 1035, 1031, 1033, 1038, 1041,
- /* 260 */ 1014, 1020, 1046, 1047, 1023, 1028, 1022, 1027, 1049, 1029,
- /* 270 */ 1036, 1040, 1042, 1048, 1024, 1051, 1025, 1050, 1053, 1062,
- /* 280 */ 1054, 1058, 1059, 1063, 1057, 1064, 1065,
+ /* 50 */ -217, -217, -217, -217, 469, 484, 568, 710, 712, 714,
+ /* 60 */ 719, 721, 726, 747, 752, 754, 760, 763, 768, 792,
+ /* 70 */ 802, 804, 806, 809, 844, 853, 855, 857, 859, 873,
+ /* 80 */ 883, 892, 897, 900, 903, 918, 924, 928, 931, 933,
+ /* 90 */ 935, 944, 952, -217, -217, 408, -217, -217, -217, -217,
+ /* 100 */ -32, 219, 153, 332, 503, 505, 508, 583, 476, -139,
+ /* 110 */ -217, -217, -217, -217, 141, 21, 19, 67, 313, 313,
+ /* 120 */ 299, 145, 230, 426, 223, 595, 483, 430, 667, 597,
+ /* 130 */ 627, 631, 637, 675, 676, 588, 677, -5, 460, 671,
+ /* 140 */ 751, 765, 628, 487, 589, -112, -57, 18, 143, 118,
+ /* 150 */ 213, 118, 118, 244, 331, 352, 416, 480, 527, 545,
+ /* 160 */ 626, 596, 480, 697, 832, 794, 851, 625, 860, 864,
+ /* 170 */ 118, 625, 868, 885, 862, 867, 882, 916, 917, 118,
+ /* 180 */ 934, 942, 118, 945, 852, 878, 949, 964, 118, 965,
+ /* 190 */ 968, 969, 118, 970, 973, 976, 118, 118, 977, 978,
+ /* 200 */ 979, 980, 981, 982, 983, 939, 938, 905, 906, 912,
+ /* 210 */ 966, 967, 972, 959, 974, 975, 986, 943, 946, 996,
+ /* 220 */ 997, 999, 1002, 998, 961, 957, 960, 962, 963, 987,
+ /* 230 */ 941, 1013, 956, 1009, 988, 1018, 989, 990, 992, 993,
+ /* 240 */ 1003, 1004, 1000, 1006, 1007, 1010, 1012, 991, 994, 1023,
+ /* 250 */ 1005, 1017, 1019, 1020, 1026, 1038, 1040, 1043, 1045, 1053,
+ /* 260 */ 1049, 1051, 995, 1001, 1059, 1056, 1028, 1029, 1008, 1021,
+ /* 270 */ 1062, 1033, 1034, 1035, 1039, 1024, 1046, 1014, 1065, 1011,
+ /* 280 */ 1022, 1072, 1079, 1025, 1066, 1061, 1063, 1044, 1047, 1048,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 587, 813, 890, 702, 890, 813, 890, 813, 890, 706,
- /* 10 */ 864, 809, 813, 890, 890, 890, 784, 890, 835, 890,
- /* 20 */ 618, 835, 835, 737, 890, 890, 890, 890, 890, 890,
- /* 30 */ 890, 890, 738, 890, 812, 808, 804, 806, 805, 739,
- /* 40 */ 726, 735, 742, 718, 849, 744, 745, 750, 751, 865,
- /* 50 */ 868, 772, 790, 771, 890, 890, 890, 890, 890, 890,
- /* 60 */ 890, 890, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 70 */ 890, 890, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 80 */ 890, 890, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 90 */ 890, 890, 890, 774, 795, 611, 773, 783, 775, 776,
- /* 100 */ 671, 606, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 110 */ 777, 778, 791, 792, 890, 890, 890, 890, 890, 890,
- /* 120 */ 587, 702, 890, 702, 890, 890, 890, 890, 890, 890,
- /* 130 */ 890, 890, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 140 */ 890, 890, 696, 706, 883, 890, 890, 662, 890, 890,
- /* 150 */ 890, 890, 890, 890, 890, 890, 890, 890, 594, 592,
- /* 160 */ 890, 694, 890, 890, 620, 890, 890, 704, 890, 890,
- /* 170 */ 709, 710, 890, 890, 890, 890, 890, 890, 890, 608,
- /* 180 */ 890, 890, 683, 890, 841, 890, 890, 890, 856, 890,
- /* 190 */ 890, 890, 854, 890, 890, 890, 685, 747, 823, 890,
- /* 200 */ 890, 869, 871, 890, 890, 729, 694, 703, 890, 890,
- /* 210 */ 807, 729, 729, 641, 729, 729, 644, 741, 741, 591,
- /* 220 */ 591, 591, 591, 661, 673, 673, 658, 673, 644, 673,
- /* 230 */ 890, 741, 732, 734, 722, 736, 890, 711, 730, 890,
- /* 240 */ 730, 711, 719, 721, 719, 721, 817, 730, 730, 890,
- /* 250 */ 658, 673, 673, 673, 817, 603, 711, 711, 711, 711,
- /* 260 */ 845, 848, 603, 711, 675, 675, 752, 741, 711, 682,
- /* 270 */ 682, 682, 741, 675, 752, 711, 867, 867, 711, 711,
- /* 280 */ 876, 628, 646, 646, 851, 883, 888, 890, 890, 890,
- /* 290 */ 890, 890, 890, 759, 890, 890, 890, 890, 890, 890,
- /* 300 */ 890, 890, 890, 890, 890, 890, 890, 890, 830, 890,
- /* 310 */ 890, 890, 890, 890, 890, 890, 764, 760, 890, 761,
- /* 320 */ 890, 890, 890, 890, 688, 890, 890, 890, 890, 890,
- /* 330 */ 890, 890, 723, 890, 733, 890, 890, 890, 890, 890,
- /* 340 */ 890, 890, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 350 */ 890, 890, 890, 890, 843, 844, 890, 890, 890, 890,
- /* 360 */ 890, 890, 890, 890, 890, 890, 890, 890, 890, 890,
- /* 370 */ 890, 890, 890, 890, 890, 890, 890, 875, 890, 890,
- /* 380 */ 878, 588, 890, 582, 585, 584, 586, 590, 593, 615,
- /* 390 */ 616, 617, 595, 596, 597, 598, 599, 600, 601, 607,
- /* 400 */ 609, 627, 629, 636, 674, 677, 678, 679, 859, 860,
- /* 410 */ 861, 637, 656, 659, 660, 638, 645, 727, 728, 639,
- /* 420 */ 692, 693, 756, 686, 687, 691, 758, 762, 763, 765,
- /* 430 */ 766, 614, 621, 622, 625, 626, 831, 833, 832, 834,
- /* 440 */ 624, 623, 767, 770, 779, 780, 782, 788, 794, 797,
- /* 450 */ 781, 786, 787, 789, 793, 796, 689, 690, 800, 802,
- /* 460 */ 803, 857, 858, 798, 810, 811, 712, 801, 785, 724,
- /* 470 */ 613, 731, 725, 695, 705, 714, 715, 716, 717, 700,
- /* 480 */ 701, 707, 720, 754, 755, 708, 697, 698, 699, 799,
- /* 490 */ 757, 768, 769, 640, 647, 648, 649, 652, 653, 654,
- /* 500 */ 655, 650, 651, 818, 819, 821, 820, 642, 643, 657,
- /* 510 */ 630, 631, 632, 633, 764, 634, 635, 619, 612, 663,
- /* 520 */ 666, 667, 668, 669, 670, 672, 664, 665, 610, 602,
- /* 530 */ 604, 713, 837, 846, 847, 842, 838, 839, 840, 605,
- /* 540 */ 814, 815, 676, 748, 749, 836, 850, 852, 753, 853,
- /* 550 */ 855, 880, 680, 681, 684, 822, 862, 740, 743, 746,
- /* 560 */ 824, 825, 826, 827, 828, 829, 863, 866, 870, 872,
- /* 570 */ 873, 874, 877, 879, 884, 885, 886, 889, 887, 589,
- /* 580 */ 583,
+ /* 0 */ 592, 819, 896, 707, 896, 819, 896, 819, 896, 711,
+ /* 10 */ 870, 815, 819, 896, 896, 896, 790, 896, 841, 896,
+ /* 20 */ 623, 841, 841, 742, 896, 896, 896, 896, 896, 896,
+ /* 30 */ 896, 896, 743, 896, 818, 814, 810, 812, 811, 744,
+ /* 40 */ 731, 740, 747, 723, 855, 749, 750, 756, 757, 871,
+ /* 50 */ 874, 778, 796, 777, 896, 896, 896, 896, 896, 896,
+ /* 60 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 70 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 80 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 90 */ 896, 896, 896, 780, 801, 616, 779, 789, 781, 782,
+ /* 100 */ 676, 611, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 110 */ 783, 784, 797, 798, 896, 896, 896, 896, 896, 896,
+ /* 120 */ 592, 707, 896, 707, 896, 896, 896, 896, 896, 896,
+ /* 130 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 140 */ 896, 896, 701, 711, 889, 896, 896, 667, 896, 896,
+ /* 150 */ 896, 896, 896, 896, 896, 896, 896, 896, 599, 597,
+ /* 160 */ 896, 699, 896, 896, 625, 896, 896, 709, 896, 896,
+ /* 170 */ 714, 715, 896, 896, 896, 896, 896, 896, 896, 613,
+ /* 180 */ 896, 896, 688, 896, 847, 896, 896, 896, 862, 896,
+ /* 190 */ 896, 896, 860, 896, 896, 896, 690, 752, 829, 896,
+ /* 200 */ 896, 875, 877, 896, 896, 699, 708, 896, 896, 813,
+ /* 210 */ 734, 734, 734, 646, 734, 734, 649, 746, 746, 596,
+ /* 220 */ 596, 596, 596, 666, 896, 746, 737, 739, 727, 741,
+ /* 230 */ 896, 716, 735, 896, 735, 716, 724, 726, 724, 726,
+ /* 240 */ 678, 678, 663, 678, 649, 678, 823, 735, 735, 896,
+ /* 250 */ 663, 678, 678, 678, 823, 608, 716, 608, 716, 608,
+ /* 260 */ 716, 716, 851, 854, 608, 716, 680, 680, 758, 746,
+ /* 270 */ 716, 687, 687, 687, 687, 746, 680, 758, 716, 873,
+ /* 280 */ 873, 716, 716, 882, 633, 651, 651, 857, 889, 894,
+ /* 290 */ 896, 896, 896, 896, 765, 896, 896, 896, 896, 896,
+ /* 300 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 310 */ 896, 836, 896, 896, 896, 896, 770, 766, 896, 767,
+ /* 320 */ 896, 896, 896, 896, 693, 896, 896, 896, 896, 896,
+ /* 330 */ 896, 896, 728, 896, 738, 896, 896, 896, 896, 896,
+ /* 340 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 350 */ 896, 896, 896, 896, 896, 896, 896, 849, 850, 896,
+ /* 360 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 370 */ 896, 896, 896, 896, 896, 896, 896, 896, 896, 896,
+ /* 380 */ 896, 881, 896, 896, 884, 593, 896, 587, 590, 589,
+ /* 390 */ 591, 595, 598, 620, 621, 622, 600, 601, 602, 603,
+ /* 400 */ 604, 605, 606, 612, 614, 632, 634, 618, 636, 697,
+ /* 410 */ 698, 762, 691, 692, 696, 764, 768, 769, 771, 772,
+ /* 420 */ 619, 626, 627, 630, 631, 837, 839, 838, 840, 629,
+ /* 430 */ 628, 773, 776, 785, 786, 788, 794, 800, 803, 787,
+ /* 440 */ 792, 793, 795, 799, 802, 694, 695, 806, 808, 809,
+ /* 450 */ 863, 864, 865, 866, 867, 804, 816, 817, 717, 807,
+ /* 460 */ 791, 729, 732, 733, 736, 730, 700, 710, 719, 720,
+ /* 470 */ 721, 722, 705, 706, 712, 725, 760, 761, 713, 702,
+ /* 480 */ 703, 704, 805, 763, 774, 775, 637, 638, 770, 639,
+ /* 490 */ 640, 641, 679, 682, 683, 684, 642, 661, 664, 665,
+ /* 500 */ 643, 650, 644, 645, 652, 653, 654, 657, 658, 659,
+ /* 510 */ 660, 655, 656, 824, 825, 827, 826, 647, 648, 662,
+ /* 520 */ 635, 624, 617, 668, 671, 672, 673, 674, 675, 677,
+ /* 530 */ 669, 670, 615, 607, 609, 718, 843, 852, 853, 848,
+ /* 540 */ 844, 845, 846, 610, 820, 821, 681, 754, 755, 842,
+ /* 550 */ 856, 858, 759, 859, 861, 886, 685, 686, 689, 828,
+ /* 560 */ 868, 745, 748, 751, 753, 830, 831, 832, 833, 834,
+ /* 570 */ 835, 869, 872, 876, 878, 879, 880, 883, 885, 890,
+ /* 580 */ 891, 892, 895, 893, 594, 588,
};
#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
@@ -922,11 +922,11 @@ static const char *const yyRuleName[] =
/* 47 */ "carglist ::=",
/* 48 */ "carg ::= CONSTRAINT nm ccons",
/* 49 */ "carg ::= ccons",
- /* 50 */ "carg ::= DEFAULT term",
- /* 51 */ "carg ::= DEFAULT LP expr RP",
- /* 52 */ "carg ::= DEFAULT PLUS term",
- /* 53 */ "carg ::= DEFAULT MINUS term",
- /* 54 */ "carg ::= DEFAULT id",
+ /* 50 */ "ccons ::= DEFAULT term",
+ /* 51 */ "ccons ::= DEFAULT LP expr RP",
+ /* 52 */ "ccons ::= DEFAULT PLUS term",
+ /* 53 */ "ccons ::= DEFAULT MINUS term",
+ /* 54 */ "ccons ::= DEFAULT id",
/* 55 */ "ccons ::= NULL onconf",
/* 56 */ "ccons ::= NOT NULL onconf",
/* 57 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
@@ -974,7 +974,7 @@ static const char *const yyRuleName[] =
/* 99 */ "cmd ::= DROP TABLE ifexists fullname",
/* 100 */ "ifexists ::= IF EXISTS",
/* 101 */ "ifexists ::=",
- /* 102 */ "cmd ::= CREATE temp VIEW nm dbnm AS select",
+ /* 102 */ "cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select",
/* 103 */ "cmd ::= DROP VIEW ifexists fullname",
/* 104 */ "cmd ::= select",
/* 105 */ "select ::= oneselect",
@@ -1039,148 +1039,149 @@ static const char *const yyRuleName[] =
/* 164 */ "setlist ::= nm EQ expr",
/* 165 */ "cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP",
/* 166 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 167 */ "insert_cmd ::= INSERT orconf",
- /* 168 */ "insert_cmd ::= REPLACE",
- /* 169 */ "itemlist ::= itemlist COMMA expr",
- /* 170 */ "itemlist ::= expr",
- /* 171 */ "inscollist_opt ::=",
- /* 172 */ "inscollist_opt ::= LP inscollist RP",
- /* 173 */ "inscollist ::= inscollist COMMA nm",
- /* 174 */ "inscollist ::= nm",
- /* 175 */ "expr ::= term",
- /* 176 */ "expr ::= LP expr RP",
- /* 177 */ "term ::= NULL",
- /* 178 */ "expr ::= ID",
- /* 179 */ "expr ::= JOIN_KW",
- /* 180 */ "expr ::= nm DOT nm",
- /* 181 */ "expr ::= nm DOT nm DOT nm",
- /* 182 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 183 */ "term ::= STRING",
- /* 184 */ "expr ::= REGISTER",
- /* 185 */ "expr ::= VARIABLE",
- /* 186 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 187 */ "expr ::= ID LP distinct exprlist RP",
- /* 188 */ "expr ::= ID LP STAR RP",
- /* 189 */ "term ::= CTIME_KW",
- /* 190 */ "expr ::= expr AND expr",
- /* 191 */ "expr ::= expr OR expr",
- /* 192 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 193 */ "expr ::= expr EQ|NE expr",
- /* 194 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 195 */ "expr ::= expr PLUS|MINUS expr",
- /* 196 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 197 */ "expr ::= expr CONCAT expr",
- /* 198 */ "likeop ::= LIKE_KW",
- /* 199 */ "likeop ::= NOT LIKE_KW",
- /* 200 */ "likeop ::= MATCH",
- /* 201 */ "likeop ::= NOT MATCH",
- /* 202 */ "escape ::= ESCAPE expr",
- /* 203 */ "escape ::=",
- /* 204 */ "expr ::= expr likeop expr escape",
- /* 205 */ "expr ::= expr ISNULL|NOTNULL",
- /* 206 */ "expr ::= expr IS NULL",
- /* 207 */ "expr ::= expr NOT NULL",
- /* 208 */ "expr ::= expr IS NOT NULL",
- /* 209 */ "expr ::= NOT|BITNOT expr",
- /* 210 */ "expr ::= MINUS expr",
- /* 211 */ "expr ::= PLUS expr",
- /* 212 */ "between_op ::= BETWEEN",
- /* 213 */ "between_op ::= NOT BETWEEN",
- /* 214 */ "expr ::= expr between_op expr AND expr",
- /* 215 */ "in_op ::= IN",
- /* 216 */ "in_op ::= NOT IN",
- /* 217 */ "expr ::= expr in_op LP exprlist RP",
- /* 218 */ "expr ::= LP select RP",
- /* 219 */ "expr ::= expr in_op LP select RP",
- /* 220 */ "expr ::= expr in_op nm dbnm",
- /* 221 */ "expr ::= EXISTS LP select RP",
- /* 222 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 223 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 224 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 225 */ "case_else ::= ELSE expr",
- /* 226 */ "case_else ::=",
- /* 227 */ "case_operand ::= expr",
- /* 228 */ "case_operand ::=",
- /* 229 */ "exprlist ::= exprlist COMMA expritem",
- /* 230 */ "exprlist ::= expritem",
- /* 231 */ "expritem ::= expr",
- /* 232 */ "expritem ::=",
- /* 233 */ "cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
- /* 234 */ "uniqueflag ::= UNIQUE",
- /* 235 */ "uniqueflag ::=",
- /* 236 */ "idxlist_opt ::=",
- /* 237 */ "idxlist_opt ::= LP idxlist RP",
- /* 238 */ "idxlist ::= idxlist COMMA idxitem collate sortorder",
- /* 239 */ "idxlist ::= idxitem collate sortorder",
- /* 240 */ "idxitem ::= nm",
- /* 241 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 242 */ "cmd ::= VACUUM",
- /* 243 */ "cmd ::= VACUUM nm",
- /* 244 */ "cmd ::= PRAGMA nm dbnm EQ nm",
- /* 245 */ "cmd ::= PRAGMA nm dbnm EQ ON",
- /* 246 */ "cmd ::= PRAGMA nm dbnm EQ plus_num",
- /* 247 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 248 */ "cmd ::= PRAGMA nm dbnm LP nm RP",
- /* 249 */ "cmd ::= PRAGMA nm dbnm",
- /* 250 */ "plus_num ::= plus_opt number",
- /* 251 */ "minus_num ::= MINUS number",
- /* 252 */ "number ::= INTEGER|FLOAT",
- /* 253 */ "plus_opt ::= PLUS",
- /* 254 */ "plus_opt ::=",
- /* 255 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
- /* 256 */ "trigger_decl ::= temp TRIGGER nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 257 */ "trigger_time ::= BEFORE",
- /* 258 */ "trigger_time ::= AFTER",
- /* 259 */ "trigger_time ::= INSTEAD OF",
- /* 260 */ "trigger_time ::=",
- /* 261 */ "trigger_event ::= DELETE|INSERT",
- /* 262 */ "trigger_event ::= UPDATE",
- /* 263 */ "trigger_event ::= UPDATE OF inscollist",
- /* 264 */ "foreach_clause ::=",
- /* 265 */ "foreach_clause ::= FOR EACH ROW",
- /* 266 */ "foreach_clause ::= FOR EACH STATEMENT",
- /* 267 */ "when_clause ::=",
- /* 268 */ "when_clause ::= WHEN expr",
- /* 269 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 270 */ "trigger_cmd_list ::=",
- /* 271 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
- /* 272 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
- /* 273 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
- /* 274 */ "trigger_cmd ::= DELETE FROM nm where_opt",
- /* 275 */ "trigger_cmd ::= select",
- /* 276 */ "expr ::= RAISE LP IGNORE RP",
- /* 277 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 278 */ "raisetype ::= ROLLBACK",
- /* 279 */ "raisetype ::= ABORT",
- /* 280 */ "raisetype ::= FAIL",
- /* 281 */ "cmd ::= DROP TRIGGER fullname",
- /* 282 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 283 */ "key_opt ::=",
- /* 284 */ "key_opt ::= KEY expr",
- /* 285 */ "database_kw_opt ::= DATABASE",
- /* 286 */ "database_kw_opt ::=",
- /* 287 */ "cmd ::= DETACH database_kw_opt expr",
- /* 288 */ "cmd ::= REINDEX",
- /* 289 */ "cmd ::= REINDEX nm dbnm",
- /* 290 */ "cmd ::= ANALYZE",
- /* 291 */ "cmd ::= ANALYZE nm dbnm",
- /* 292 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 293 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 294 */ "add_column_fullname ::= fullname",
- /* 295 */ "kwcolumn_opt ::=",
- /* 296 */ "kwcolumn_opt ::= COLUMNKW",
- /* 297 */ "cmd ::= create_vtab",
- /* 298 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 299 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
- /* 300 */ "vtabarglist ::= vtabarg",
- /* 301 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 302 */ "vtabarg ::=",
- /* 303 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 304 */ "vtabargtoken ::= ANY",
- /* 305 */ "vtabargtoken ::= lp anylist RP",
- /* 306 */ "lp ::= LP",
- /* 307 */ "anylist ::=",
- /* 308 */ "anylist ::= anylist ANY",
+ /* 167 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 168 */ "insert_cmd ::= INSERT orconf",
+ /* 169 */ "insert_cmd ::= REPLACE",
+ /* 170 */ "itemlist ::= itemlist COMMA expr",
+ /* 171 */ "itemlist ::= expr",
+ /* 172 */ "inscollist_opt ::=",
+ /* 173 */ "inscollist_opt ::= LP inscollist RP",
+ /* 174 */ "inscollist ::= inscollist COMMA nm",
+ /* 175 */ "inscollist ::= nm",
+ /* 176 */ "expr ::= term",
+ /* 177 */ "expr ::= LP expr RP",
+ /* 178 */ "term ::= NULL",
+ /* 179 */ "expr ::= ID",
+ /* 180 */ "expr ::= JOIN_KW",
+ /* 181 */ "expr ::= nm DOT nm",
+ /* 182 */ "expr ::= nm DOT nm DOT nm",
+ /* 183 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 184 */ "term ::= STRING",
+ /* 185 */ "expr ::= REGISTER",
+ /* 186 */ "expr ::= VARIABLE",
+ /* 187 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 188 */ "expr ::= ID LP distinct exprlist RP",
+ /* 189 */ "expr ::= ID LP STAR RP",
+ /* 190 */ "term ::= CTIME_KW",
+ /* 191 */ "expr ::= expr AND expr",
+ /* 192 */ "expr ::= expr OR expr",
+ /* 193 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 194 */ "expr ::= expr EQ|NE expr",
+ /* 195 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 196 */ "expr ::= expr PLUS|MINUS expr",
+ /* 197 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 198 */ "expr ::= expr CONCAT expr",
+ /* 199 */ "likeop ::= LIKE_KW",
+ /* 200 */ "likeop ::= NOT LIKE_KW",
+ /* 201 */ "likeop ::= MATCH",
+ /* 202 */ "likeop ::= NOT MATCH",
+ /* 203 */ "escape ::= ESCAPE expr",
+ /* 204 */ "escape ::=",
+ /* 205 */ "expr ::= expr likeop expr escape",
+ /* 206 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 207 */ "expr ::= expr IS NULL",
+ /* 208 */ "expr ::= expr NOT NULL",
+ /* 209 */ "expr ::= expr IS NOT NULL",
+ /* 210 */ "expr ::= NOT|BITNOT expr",
+ /* 211 */ "expr ::= MINUS expr",
+ /* 212 */ "expr ::= PLUS expr",
+ /* 213 */ "between_op ::= BETWEEN",
+ /* 214 */ "between_op ::= NOT BETWEEN",
+ /* 215 */ "expr ::= expr between_op expr AND expr",
+ /* 216 */ "in_op ::= IN",
+ /* 217 */ "in_op ::= NOT IN",
+ /* 218 */ "expr ::= expr in_op LP exprlist RP",
+ /* 219 */ "expr ::= LP select RP",
+ /* 220 */ "expr ::= expr in_op LP select RP",
+ /* 221 */ "expr ::= expr in_op nm dbnm",
+ /* 222 */ "expr ::= EXISTS LP select RP",
+ /* 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 ifnotexists nm dbnm ON nm LP idxlist RP",
+ /* 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 ifexists 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|FLOAT",
+ /* 254 */ "plus_opt ::= PLUS",
+ /* 255 */ "plus_opt ::=",
+ /* 256 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
+ /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 258 */ "trigger_time ::= BEFORE",
+ /* 259 */ "trigger_time ::= AFTER",
+ /* 260 */ "trigger_time ::= INSTEAD OF",
+ /* 261 */ "trigger_time ::=",
+ /* 262 */ "trigger_event ::= DELETE|INSERT",
+ /* 263 */ "trigger_event ::= UPDATE",
+ /* 264 */ "trigger_event ::= UPDATE OF inscollist",
+ /* 265 */ "foreach_clause ::=",
+ /* 266 */ "foreach_clause ::= FOR EACH ROW",
+ /* 267 */ "foreach_clause ::= FOR EACH STATEMENT",
+ /* 268 */ "when_clause ::=",
+ /* 269 */ "when_clause ::= WHEN expr",
+ /* 270 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 271 */ "trigger_cmd_list ::=",
+ /* 272 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
+ /* 273 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
+ /* 274 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
+ /* 275 */ "trigger_cmd ::= DELETE FROM nm where_opt",
+ /* 276 */ "trigger_cmd ::= select",
+ /* 277 */ "expr ::= RAISE LP IGNORE RP",
+ /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 279 */ "raisetype ::= ROLLBACK",
+ /* 280 */ "raisetype ::= ABORT",
+ /* 281 */ "raisetype ::= FAIL",
+ /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 284 */ "key_opt ::=",
+ /* 285 */ "key_opt ::= KEY expr",
+ /* 286 */ "database_kw_opt ::= DATABASE",
+ /* 287 */ "database_kw_opt ::=",
+ /* 288 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 289 */ "cmd ::= REINDEX",
+ /* 290 */ "cmd ::= REINDEX nm dbnm",
+ /* 291 */ "cmd ::= ANALYZE",
+ /* 292 */ "cmd ::= ANALYZE nm dbnm",
+ /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 294 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 295 */ "add_column_fullname ::= fullname",
+ /* 296 */ "kwcolumn_opt ::=",
+ /* 297 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 298 */ "cmd ::= create_vtab",
+ /* 299 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 300 */ "create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm",
+ /* 301 */ "vtabarglist ::= vtabarg",
+ /* 302 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 303 */ "vtabarg ::=",
+ /* 304 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 305 */ "vtabargtoken ::= ANY",
+ /* 306 */ "vtabargtoken ::= lp anylist RP",
+ /* 307 */ "lp ::= LP",
+ /* 308 */ "anylist ::=",
+ /* 309 */ "anylist ::= anylist ANY",
};
#endif /* NDEBUG */
@@ -1243,7 +1244,7 @@ static void yy_destructor(YYCODETYPE yym
case 207:
#line 374 "parse.y"
{sqlite3SelectDelete((yypminor->yy219));}
-#line 1248 "parse.c"
+#line 1249 "parse.c"
break;
case 170:
case 171:
@@ -1256,9 +1257,9 @@ static void yy_destructor(YYCODETYPE yym
case 224:
case 225:
case 235:
-#line 631 "parse.y"
+#line 618 "parse.y"
{sqlite3ExprDelete((yypminor->yy172));}
-#line 1263 "parse.c"
+#line 1264 "parse.c"
break;
case 175:
case 183:
@@ -1271,48 +1272,48 @@ static void yy_destructor(YYCODETYPE yym
case 214:
case 217:
case 223:
-#line 865 "parse.y"
+#line 855 "parse.y"
{sqlite3ExprListDelete((yypminor->yy174));}
-#line 1278 "parse.c"
+#line 1279 "parse.c"
break;
case 189:
case 194:
case 202:
case 203:
-#line 502 "parse.y"
+#line 487 "parse.y"
{sqlite3SrcListDelete((yypminor->yy373));}
-#line 1286 "parse.c"
+#line 1287 "parse.c"
break;
case 199:
-#line 563 "parse.y"
+#line 548 "parse.y"
{
sqlite3ExprDelete((yypminor->yy234).pLimit);
sqlite3ExprDelete((yypminor->yy234).pOffset);
}
-#line 1294 "parse.c"
+#line 1295 "parse.c"
break;
case 206:
case 209:
case 216:
-#line 519 "parse.y"
+#line 504 "parse.y"
{sqlite3IdListDelete((yypminor->yy432));}
-#line 1301 "parse.c"
+#line 1302 "parse.c"
break;
case 231:
case 236:
-#line 959 "parse.y"
+#line 951 "parse.y"
{sqlite3DeleteTriggerStep((yypminor->yy243));}
-#line 1307 "parse.c"
+#line 1308 "parse.c"
break;
case 233:
-#line 943 "parse.y"
+#line 935 "parse.y"
{sqlite3IdListDelete((yypminor->yy370).b);}
-#line 1312 "parse.c"
+#line 1313 "parse.c"
break;
case 238:
-#line 1027 "parse.y"
+#line 1019 "parse.y"
{sqlite3ExprDelete((yypminor->yy386));}
-#line 1317 "parse.c"
+#line 1318 "parse.c"
break;
default: break; /* If no destructor action specified: do nothing */
}
@@ -1480,7 +1481,7 @@ static void yy_shift(
sqlite3ErrorMsg(pParse, "parser stack overflow");
pParse->parseError = 1;
-#line 1486 "parse.c"
+#line 1487 "parse.c"
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument var */
return;
}
@@ -1557,13 +1558,13 @@ static const struct {
{ 160, 0 },
{ 168, 3 },
{ 168, 1 },
- { 168, 2 },
- { 168, 4 },
- { 168, 3 },
- { 168, 3 },
- { 168, 2 },
{ 169, 2 },
+ { 169, 4 },
{ 169, 3 },
+ { 169, 3 },
+ { 169, 2 },
+ { 169, 2 },
+ { 169, 3 },
{ 169, 5 },
{ 169, 2 },
{ 169, 4 },
@@ -1609,7 +1610,7 @@ static const struct {
{ 144, 4 },
{ 188, 2 },
{ 188, 0 },
- { 144, 7 },
+ { 144, 8 },
{ 144, 4 },
{ 144, 1 },
{ 156, 1 },
@@ -1674,6 +1675,7 @@ static const struct {
{ 214, 3 },
{ 144, 8 },
{ 144, 5 },
+ { 144, 6 },
{ 215, 2 },
{ 215, 1 },
{ 217, 3 },
@@ -1763,7 +1765,7 @@ static const struct {
{ 228, 1 },
{ 228, 0 },
{ 144, 5 },
- { 230, 10 },
+ { 230, 11 },
{ 232, 1 },
{ 232, 1 },
{ 232, 2 },
@@ -1788,7 +1790,7 @@ static const struct {
{ 187, 1 },
{ 187, 1 },
{ 187, 1 },
- { 144, 3 },
+ { 144, 4 },
{ 144, 6 },
{ 238, 0 },
{ 238, 2 },
@@ -1867,32 +1869,32 @@ static void yy_reduce(
case 3:
#line 100 "parse.y"
{ sqlite3FinishCoding(pParse); }
-#line 1873 "parse.c"
+#line 1875 "parse.c"
break;
case 6:
#line 103 "parse.y"
{ sqlite3BeginParse(pParse, 0); }
-#line 1878 "parse.c"
+#line 1880 "parse.c"
break;
case 7:
#line 105 "parse.y"
{ sqlite3BeginParse(pParse, 1); }
-#line 1883 "parse.c"
+#line 1885 "parse.c"
break;
case 8:
#line 106 "parse.y"
{ sqlite3BeginParse(pParse, 2); }
-#line 1888 "parse.c"
+#line 1890 "parse.c"
break;
case 9:
#line 112 "parse.y"
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy46);}
-#line 1893 "parse.c"
+#line 1895 "parse.c"
break;
case 13:
#line 117 "parse.y"
{yygotominor.yy46 = TK_DEFERRED;}
-#line 1898 "parse.c"
+#line 1900 "parse.c"
break;
case 14:
case 15:
@@ -1901,25 +1903,25 @@ static void yy_reduce(
case 109:
#line 118 "parse.y"
{yygotominor.yy46 = yymsp[0].major;}
-#line 1907 "parse.c"
+#line 1909 "parse.c"
break;
case 17:
case 18:
#line 121 "parse.y"
{sqlite3CommitTransaction(pParse);}
-#line 1913 "parse.c"
+#line 1915 "parse.c"
break;
case 19:
#line 123 "parse.y"
{sqlite3RollbackTransaction(pParse);}
-#line 1918 "parse.c"
+#line 1920 "parse.c"
break;
case 21:
#line 128 "parse.y"
{
sqlite3StartTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46);
}
-#line 1925 "parse.c"
+#line 1927 "parse.c"
break;
case 22:
case 25:
@@ -1930,11 +1932,11 @@ static void yy_reduce(
case 101:
case 112:
case 113:
- case 212:
- case 215:
+ case 213:
+ case 216:
#line 132 "parse.y"
{yygotominor.yy46 = 0;}
-#line 1940 "parse.c"
+#line 1942 "parse.c"
break;
case 23:
case 24:
@@ -1942,18 +1944,18 @@ static void yy_reduce(
case 78:
case 100:
case 111:
- case 213:
- case 216:
+ case 214:
+ case 217:
#line 133 "parse.y"
{yygotominor.yy46 = 1;}
-#line 1952 "parse.c"
+#line 1954 "parse.c"
break;
case 26:
#line 139 "parse.y"
{
sqlite3EndTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy0,0);
}
-#line 1959 "parse.c"
+#line 1961 "parse.c"
break;
case 27:
#line 142 "parse.y"
@@ -1961,7 +1963,7 @@ static void yy_reduce(
sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy219);
sqlite3SelectDelete(yymsp[0].minor.yy219);
}
-#line 1967 "parse.c"
+#line 1969 "parse.c"
break;
case 30:
#line 154 "parse.y"
@@ -1969,7 +1971,7 @@ static void yy_reduce(
yygotominor.yy410.z = yymsp[-2].minor.yy410.z;
yygotominor.yy410.n = (pParse->sLastToken.z-yymsp[-2].minor.yy410.z) + pParse->sLastToken.n;
}
-#line 1975 "parse.c"
+#line 1977 "parse.c"
break;
case 31:
#line 158 "parse.y"
@@ -1977,22 +1979,22 @@ static void yy_reduce(
sqlite3AddColumn(pParse,&yymsp[0].minor.yy410);
yygotominor.yy410 = yymsp[0].minor.yy410;
}
-#line 1983 "parse.c"
+#line 1985 "parse.c"
break;
case 32:
case 33:
case 34:
case 35:
case 36:
- case 252:
+ case 253:
#line 168 "parse.y"
{yygotominor.yy410 = yymsp[0].minor.yy0;}
-#line 1993 "parse.c"
+#line 1995 "parse.c"
break;
case 38:
#line 228 "parse.y"
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy410);}
-#line 1998 "parse.c"
+#line 2000 "parse.c"
break;
case 39:
case 42:
@@ -2000,12 +2002,12 @@ static void yy_reduce(
case 120:
case 131:
case 150:
- case 240:
- case 250:
+ case 241:
case 251:
+ case 252:
#line 229 "parse.y"
{yygotominor.yy410 = yymsp[0].minor.yy410;}
-#line 2011 "parse.c"
+#line 2013 "parse.c"
break;
case 40:
#line 230 "parse.y"
@@ -2013,7 +2015,7 @@ static void yy_reduce(
yygotominor.yy410.z = yymsp[-3].minor.yy410.z;
yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy410.z;
}
-#line 2019 "parse.c"
+#line 2021 "parse.c"
break;
case 41:
#line 234 "parse.y"
@@ -2021,33 +2023,33 @@ static void yy_reduce(
yygotominor.yy410.z = yymsp[-5].minor.yy410.z;
yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy410.z;
}
-#line 2027 "parse.c"
+#line 2029 "parse.c"
break;
case 43:
#line 240 "parse.y"
{yygotominor.yy410.z=yymsp[-1].minor.yy410.z; yygotominor.yy410.n=yymsp[0].minor.yy410.n+(yymsp[0].minor.yy410.z-yymsp[-1].minor.yy410.z);}
-#line 2032 "parse.c"
+#line 2034 "parse.c"
break;
case 44:
#line 242 "parse.y"
{ yygotominor.yy46 = atoi((char*)yymsp[0].minor.yy410.z); }
-#line 2037 "parse.c"
+#line 2039 "parse.c"
break;
case 45:
#line 243 "parse.y"
{ yygotominor.yy46 = -atoi((char*)yymsp[0].minor.yy410.z); }
-#line 2042 "parse.c"
+#line 2044 "parse.c"
break;
case 50:
case 52:
#line 252 "parse.y"
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy172);}
-#line 2048 "parse.c"
+#line 2050 "parse.c"
break;
case 51:
#line 253 "parse.y"
{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy172);}
-#line 2053 "parse.c"
+#line 2055 "parse.c"
break;
case 53:
#line 255 "parse.y"
@@ -2055,7 +2057,7 @@ static void yy_reduce(
Expr *p = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
sqlite3AddDefaultValue(pParse,p);
}
-#line 2061 "parse.c"
+#line 2063 "parse.c"
break;
case 54:
#line 259 "parse.y"
@@ -2063,92 +2065,92 @@ static void yy_reduce(
Expr *p = sqlite3Expr(TK_STRING, 0, 0, &yymsp[0].minor.yy410);
sqlite3AddDefaultValue(pParse,p);
}
-#line 2069 "parse.c"
+#line 2071 "parse.c"
break;
case 56:
#line 268 "parse.y"
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy46);}
-#line 2074 "parse.c"
+#line 2076 "parse.c"
break;
case 57:
#line 270 "parse.y"
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy46,yymsp[0].minor.yy46,yymsp[-2].minor.yy46);}
-#line 2079 "parse.c"
+#line 2081 "parse.c"
break;
case 58:
#line 271 "parse.y"
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy46,0,0,0,0);}
-#line 2084 "parse.c"
+#line 2086 "parse.c"
break;
case 59:
#line 272 "parse.y"
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy172);}
-#line 2089 "parse.c"
+#line 2091 "parse.c"
break;
case 60:
#line 274 "parse.y"
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy410,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);}
-#line 2094 "parse.c"
+#line 2096 "parse.c"
break;
case 61:
#line 275 "parse.y"
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);}
-#line 2099 "parse.c"
+#line 2101 "parse.c"
break;
case 62:
#line 276 "parse.y"
{sqlite3AddCollateType(pParse, (char*)yymsp[0].minor.yy410.z, yymsp[0].minor.yy410.n);}
-#line 2104 "parse.c"
+#line 2106 "parse.c"
break;
case 65:
#line 289 "parse.y"
{ yygotominor.yy46 = OE_Restrict * 0x010101; }
-#line 2109 "parse.c"
+#line 2111 "parse.c"
break;
case 66:
#line 290 "parse.y"
{ yygotominor.yy46 = (yymsp[-1].minor.yy46 & yymsp[0].minor.yy405.mask) | yymsp[0].minor.yy405.value; }
-#line 2114 "parse.c"
+#line 2116 "parse.c"
break;
case 67:
#line 292 "parse.y"
{ yygotominor.yy405.value = 0; yygotominor.yy405.mask = 0x000000; }
-#line 2119 "parse.c"
+#line 2121 "parse.c"
break;
case 68:
#line 293 "parse.y"
{ yygotominor.yy405.value = yymsp[0].minor.yy46; yygotominor.yy405.mask = 0x0000ff; }
-#line 2124 "parse.c"
+#line 2126 "parse.c"
break;
case 69:
#line 294 "parse.y"
{ yygotominor.yy405.value = yymsp[0].minor.yy46<<8; yygotominor.yy405.mask = 0x00ff00; }
-#line 2129 "parse.c"
+#line 2131 "parse.c"
break;
case 70:
#line 295 "parse.y"
{ yygotominor.yy405.value = yymsp[0].minor.yy46<<16; yygotominor.yy405.mask = 0xff0000; }
-#line 2134 "parse.c"
+#line 2136 "parse.c"
break;
case 71:
#line 297 "parse.y"
{ yygotominor.yy46 = OE_SetNull; }
-#line 2139 "parse.c"
+#line 2141 "parse.c"
break;
case 72:
#line 298 "parse.y"
{ yygotominor.yy46 = OE_SetDflt; }
-#line 2144 "parse.c"
+#line 2146 "parse.c"
break;
case 73:
#line 299 "parse.y"
{ yygotominor.yy46 = OE_Cascade; }
-#line 2149 "parse.c"
+#line 2151 "parse.c"
break;
case 74:
#line 300 "parse.y"
{ yygotominor.yy46 = OE_Restrict; }
-#line 2154 "parse.c"
+#line 2156 "parse.c"
break;
case 75:
case 76:
@@ -2156,35 +2158,35 @@ static void yy_reduce(
case 93:
case 95:
case 96:
- case 167:
+ case 168:
#line 302 "parse.y"
{yygotominor.yy46 = yymsp[0].minor.yy46;}
-#line 2165 "parse.c"
+#line 2167 "parse.c"
break;
case 80:
#line 312 "parse.y"
{yygotominor.yy410.n = 0; yygotominor.yy410.z = 0;}
-#line 2170 "parse.c"
+#line 2172 "parse.c"
break;
case 81:
#line 313 "parse.y"
{yygotominor.yy410 = yymsp[-1].minor.yy0;}
-#line 2175 "parse.c"
+#line 2177 "parse.c"
break;
case 86:
#line 319 "parse.y"
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy174,yymsp[0].minor.yy46,yymsp[-2].minor.yy46,0);}
-#line 2180 "parse.c"
+#line 2182 "parse.c"
break;
case 87:
#line 321 "parse.y"
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy174,yymsp[0].minor.yy46,0,0,0,0);}
-#line 2185 "parse.c"
+#line 2187 "parse.c"
break;
case 88:
#line 322 "parse.y"
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy172);}
-#line 2190 "parse.c"
+#line 2192 "parse.c"
break;
case 89:
#line 324 "parse.y"
@@ -2192,45 +2194,45 @@ static void yy_reduce(
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy410, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46);
sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy46);
}
-#line 2198 "parse.c"
+#line 2200 "parse.c"
break;
case 92:
case 94:
#line 338 "parse.y"
{yygotominor.yy46 = OE_Default;}
-#line 2204 "parse.c"
+#line 2206 "parse.c"
break;
case 97:
#line 343 "parse.y"
{yygotominor.yy46 = OE_Ignore;}
-#line 2209 "parse.c"
+#line 2211 "parse.c"
break;
case 98:
- case 168:
+ case 169:
#line 344 "parse.y"
{yygotominor.yy46 = OE_Replace;}
-#line 2215 "parse.c"
+#line 2217 "parse.c"
break;
case 99:
#line 348 "parse.y"
{
sqlite3DropTable(pParse, yymsp[0].minor.yy373, 0, yymsp[-1].minor.yy46);
}
-#line 2222 "parse.c"
+#line 2224 "parse.c"
break;
case 102:
#line 358 "parse.y"
{
- sqlite3CreateView(pParse, &yymsp[-6].minor.yy0, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, yymsp[0].minor.yy219, yymsp[-5].minor.yy46);
+ sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, yymsp[0].minor.yy219, yymsp[-6].minor.yy46, yymsp[-4].minor.yy46);
}
-#line 2229 "parse.c"
+#line 2231 "parse.c"
break;
case 103:
#line 361 "parse.y"
{
sqlite3DropTable(pParse, yymsp[0].minor.yy373, 1, yymsp[-1].minor.yy46);
}
-#line 2236 "parse.c"
+#line 2238 "parse.c"
break;
case 104:
#line 368 "parse.y"
@@ -2238,13 +2240,13 @@ static void yy_reduce(
sqlite3Select(pParse, yymsp[0].minor.yy219, SRT_Callback, 0, 0, 0, 0, 0);
sqlite3SelectDelete(yymsp[0].minor.yy219);
}
-#line 2244 "parse.c"
+#line 2246 "parse.c"
break;
case 105:
case 128:
#line 378 "parse.y"
{yygotominor.yy219 = yymsp[0].minor.yy219;}
-#line 2250 "parse.c"
+#line 2252 "parse.c"
break;
case 106:
#line 380 "parse.y"
@@ -2255,47 +2257,47 @@ static void yy_reduce(
}
yygotominor.yy219 = yymsp[0].minor.yy219;
}
-#line 2261 "parse.c"
+#line 2263 "parse.c"
break;
case 108:
#line 389 "parse.y"
{yygotominor.yy46 = TK_ALL;}
-#line 2266 "parse.c"
+#line 2268 "parse.c"
break;
case 110:
#line 393 "parse.y"
{
yygotominor.yy219 = sqlite3SelectNew(yymsp[-6].minor.yy174,yymsp[-5].minor.yy373,yymsp[-4].minor.yy172,yymsp[-3].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy174,yymsp[-7].minor.yy46,yymsp[0].minor.yy234.pLimit,yymsp[0].minor.yy234.pOffset);
}
-#line 2273 "parse.c"
+#line 2275 "parse.c"
break;
case 114:
- case 237:
+ case 238:
#line 414 "parse.y"
{yygotominor.yy174 = yymsp[-1].minor.yy174;}
-#line 2279 "parse.c"
+#line 2281 "parse.c"
break;
case 115:
case 141:
case 151:
- case 236:
+ case 237:
#line 415 "parse.y"
{yygotominor.yy174 = 0;}
-#line 2287 "parse.c"
+#line 2289 "parse.c"
break;
case 116:
#line 416 "parse.y"
{
yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy410.n?&yymsp[0].minor.yy410:0);
}
-#line 2294 "parse.c"
+#line 2296 "parse.c"
break;
case 117:
#line 419 "parse.y"
{
yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-1].minor.yy174, sqlite3Expr(TK_ALL, 0, 0, 0), 0);
}
-#line 2301 "parse.c"
+#line 2303 "parse.c"
break;
case 118:
#line 422 "parse.y"
@@ -2304,281 +2306,271 @@ static void yy_reduce(
Expr *pLeft = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy410);
yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-3].minor.yy174, sqlite3Expr(TK_DOT, pLeft, pRight, 0), 0);
}
-#line 2310 "parse.c"
+#line 2312 "parse.c"
break;
case 121:
#line 434 "parse.y"
{yygotominor.yy410.n = 0;}
-#line 2315 "parse.c"
+#line 2317 "parse.c"
break;
case 122:
#line 446 "parse.y"
{yygotominor.yy373 = sqliteMalloc(sizeof(*yygotominor.yy373));}
-#line 2320 "parse.c"
+#line 2322 "parse.c"
break;
case 123:
#line 447 "parse.y"
-{yygotominor.yy373 = yymsp[0].minor.yy373;}
-#line 2325 "parse.c"
+{
+ yygotominor.yy373 = yymsp[0].minor.yy373;
+ sqlite3SrcListShiftJoinType(yygotominor.yy373);
+}
+#line 2330 "parse.c"
break;
case 124:
-#line 452 "parse.y"
+#line 455 "parse.y"
{
yygotominor.yy373 = yymsp[-1].minor.yy373;
if( yygotominor.yy373 && yygotominor.yy373->nSrc>0 ) yygotominor.yy373->a[yygotominor.yy373->nSrc-1].jointype = yymsp[0].minor.yy46;
}
-#line 2333 "parse.c"
+#line 2338 "parse.c"
break;
case 125:
-#line 456 "parse.y"
+#line 459 "parse.y"
{yygotominor.yy373 = 0;}
-#line 2338 "parse.c"
+#line 2343 "parse.c"
break;
case 126:
-#line 457 "parse.y"
+#line 460 "parse.y"
{
- yygotominor.yy373 = sqlite3SrcListAppend(yymsp[-5].minor.yy373,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410);
- if( yymsp[-2].minor.yy410.n ) sqlite3SrcListAddAlias(yygotominor.yy373,&yymsp[-2].minor.yy410);
- if( yymsp[-1].minor.yy172 ){
- if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pOn = yymsp[-1].minor.yy172; }
- else { sqlite3ExprDelete(yymsp[-1].minor.yy172); }
- }
- if( yymsp[0].minor.yy432 ){
- if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pUsing = yymsp[0].minor.yy432; }
- else { sqlite3IdListDelete(yymsp[0].minor.yy432); }
- }
+ yygotominor.yy373 = sqlite3SrcListAppendFromTerm(yymsp[-5].minor.yy373,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,0,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
}
-#line 2354 "parse.c"
+#line 2350 "parse.c"
break;
case 127:
-#line 471 "parse.y"
+#line 465 "parse.y"
{
- yygotominor.yy373 = sqlite3SrcListAppend(yymsp[-6].minor.yy373,0,0);
- if( yygotominor.yy373 && yygotominor.yy373->nSrc>0 ) yygotominor.yy373->a[yygotominor.yy373->nSrc-1].pSelect = yymsp[-4].minor.yy219;
- if( yymsp[-2].minor.yy410.n ) sqlite3SrcListAddAlias(yygotominor.yy373,&yymsp[-2].minor.yy410);
- if( yymsp[-1].minor.yy172 ){
- if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pOn = yymsp[-1].minor.yy172; }
- else { sqlite3ExprDelete(yymsp[-1].minor.yy172); }
- }
- if( yymsp[0].minor.yy432 ){
- if( yygotominor.yy373 && yygotominor.yy373->nSrc>1 ){ yygotominor.yy373->a[yygotominor.yy373->nSrc-2].pUsing = yymsp[0].minor.yy432; }
- else { sqlite3IdListDelete(yymsp[0].minor.yy432); }
- }
+ yygotominor.yy373 = sqlite3SrcListAppendFromTerm(yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy410,yymsp[-4].minor.yy219,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
}
-#line 2371 "parse.c"
+#line 2357 "parse.c"
break;
case 129:
-#line 492 "parse.y"
+#line 476 "parse.y"
{
+ sqlite3SrcListShiftJoinType(yymsp[0].minor.yy373);
yygotominor.yy219 = sqlite3SelectNew(0,yymsp[0].minor.yy373,0,0,0,0,0,0,0);
}
-#line 2378 "parse.c"
+#line 2365 "parse.c"
break;
case 130:
-#line 498 "parse.y"
+#line 483 "parse.y"
{yygotominor.yy410.z=0; yygotominor.yy410.n=0;}
-#line 2383 "parse.c"
+#line 2370 "parse.c"
break;
case 132:
-#line 503 "parse.y"
+#line 488 "parse.y"
{yygotominor.yy373 = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);}
-#line 2388 "parse.c"
+#line 2375 "parse.c"
break;
case 133:
-#line 507 "parse.y"
+#line 492 "parse.y"
{ yygotominor.yy46 = JT_INNER; }
-#line 2393 "parse.c"
+#line 2380 "parse.c"
break;
case 134:
-#line 508 "parse.y"
+#line 493 "parse.y"
{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
-#line 2398 "parse.c"
+#line 2385 "parse.c"
break;
case 135:
-#line 509 "parse.y"
+#line 494 "parse.y"
{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy410,0); }
-#line 2403 "parse.c"
+#line 2390 "parse.c"
break;
case 136:
-#line 511 "parse.y"
+#line 496 "parse.y"
{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy410,&yymsp[-1].minor.yy410); }
-#line 2408 "parse.c"
+#line 2395 "parse.c"
break;
case 137:
case 145:
case 154:
case 161:
- case 175:
- case 202:
- case 225:
- case 227:
- case 231:
-#line 515 "parse.y"
+ case 176:
+ case 203:
+ case 226:
+ case 228:
+ case 232:
+#line 500 "parse.y"
{yygotominor.yy172 = yymsp[0].minor.yy172;}
-#line 2421 "parse.c"
+#line 2408 "parse.c"
break;
case 138:
case 153:
case 160:
- case 203:
- case 226:
- case 228:
- case 232:
-#line 516 "parse.y"
+ case 204:
+ case 227:
+ case 229:
+ case 233:
+#line 501 "parse.y"
{yygotominor.yy172 = 0;}
-#line 2432 "parse.c"
+#line 2419 "parse.c"
break;
case 139:
- case 172:
-#line 520 "parse.y"
+ case 173:
+#line 505 "parse.y"
{yygotominor.yy432 = yymsp[-1].minor.yy432;}
-#line 2438 "parse.c"
+#line 2425 "parse.c"
break;
case 140:
- case 171:
-#line 521 "parse.y"
+ case 172:
+#line 506 "parse.y"
{yygotominor.yy432 = 0;}
-#line 2444 "parse.c"
+#line 2431 "parse.c"
break;
case 142:
case 152:
-#line 532 "parse.y"
+#line 517 "parse.y"
{yygotominor.yy174 = yymsp[0].minor.yy174;}
-#line 2450 "parse.c"
+#line 2437 "parse.c"
break;
case 143:
-#line 533 "parse.y"
+#line 518 "parse.y"
{
yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174,yymsp[-2].minor.yy172,yymsp[-1].minor.yy410.n>0?&yymsp[-1].minor.yy410:0);
if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
}
-#line 2458 "parse.c"
+#line 2445 "parse.c"
break;
case 144:
-#line 537 "parse.y"
+#line 522 "parse.y"
{
yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[-2].minor.yy172,yymsp[-1].minor.yy410.n>0?&yymsp[-1].minor.yy410:0);
if( yygotominor.yy174 && yygotominor.yy174->a ) yygotominor.yy174->a[0].sortOrder = yymsp[0].minor.yy46;
}
-#line 2466 "parse.c"
+#line 2453 "parse.c"
break;
case 146:
case 148:
-#line 546 "parse.y"
+#line 531 "parse.y"
{yygotominor.yy46 = SQLITE_SO_ASC;}
-#line 2472 "parse.c"
+#line 2459 "parse.c"
break;
case 147:
-#line 547 "parse.y"
+#line 532 "parse.y"
{yygotominor.yy46 = SQLITE_SO_DESC;}
-#line 2477 "parse.c"
+#line 2464 "parse.c"
break;
case 149:
-#line 549 "parse.y"
+#line 534 "parse.y"
{yygotominor.yy410.z = 0; yygotominor.yy410.n = 0;}
-#line 2482 "parse.c"
+#line 2469 "parse.c"
break;
case 155:
-#line 567 "parse.y"
+#line 552 "parse.y"
{yygotominor.yy234.pLimit = 0; yygotominor.yy234.pOffset = 0;}
-#line 2487 "parse.c"
+#line 2474 "parse.c"
break;
case 156:
-#line 568 "parse.y"
+#line 553 "parse.y"
{yygotominor.yy234.pLimit = yymsp[0].minor.yy172; yygotominor.yy234.pOffset = 0;}
-#line 2492 "parse.c"
+#line 2479 "parse.c"
break;
case 157:
-#line 570 "parse.y"
+#line 555 "parse.y"
{yygotominor.yy234.pLimit = yymsp[-2].minor.yy172; yygotominor.yy234.pOffset = yymsp[0].minor.yy172;}
-#line 2497 "parse.c"
+#line 2484 "parse.c"
break;
case 158:
-#line 572 "parse.y"
+#line 557 "parse.y"
{yygotominor.yy234.pOffset = yymsp[-2].minor.yy172; yygotominor.yy234.pLimit = yymsp[0].minor.yy172;}
-#line 2502 "parse.c"
+#line 2489 "parse.c"
break;
case 159:
-#line 576 "parse.y"
+#line 561 "parse.y"
{sqlite3DeleteFrom(pParse,yymsp[-1].minor.yy373,yymsp[0].minor.yy172);}
-#line 2507 "parse.c"
+#line 2494 "parse.c"
break;
case 162:
-#line 587 "parse.y"
+#line 572 "parse.y"
{sqlite3Update(pParse,yymsp[-3].minor.yy373,yymsp[-1].minor.yy174,yymsp[0].minor.yy172,yymsp[-4].minor.yy46);}
-#line 2512 "parse.c"
+#line 2499 "parse.c"
break;
case 163:
-#line 593 "parse.y"
+#line 578 "parse.y"
{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
-#line 2517 "parse.c"
+#line 2504 "parse.c"
break;
case 164:
-#line 594 "parse.y"
+#line 579 "parse.y"
{yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
-#line 2522 "parse.c"
+#line 2509 "parse.c"
break;
case 165:
-#line 600 "parse.y"
+#line 585 "parse.y"
{sqlite3Insert(pParse, yymsp[-5].minor.yy373, yymsp[-1].minor.yy174, 0, yymsp[-4].minor.yy432, yymsp[-7].minor.yy46);}
-#line 2527 "parse.c"
+#line 2514 "parse.c"
break;
case 166:
-#line 602 "parse.y"
+#line 587 "parse.y"
{sqlite3Insert(pParse, yymsp[-2].minor.yy373, 0, yymsp[0].minor.yy219, yymsp[-1].minor.yy432, yymsp[-4].minor.yy46);}
-#line 2532 "parse.c"
+#line 2519 "parse.c"
break;
- case 169:
- case 229:
-#line 612 "parse.y"
-{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);}
-#line 2538 "parse.c"
+ case 167:
+#line 589 "parse.y"
+{sqlite3Insert(pParse, yymsp[-3].minor.yy373, 0, 0, yymsp[-2].minor.yy432, yymsp[-5].minor.yy46);}
+#line 2524 "parse.c"
break;
case 170:
case 230:
-#line 613 "parse.y"
+#line 599 "parse.y"
+{yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-2].minor.yy174,yymsp[0].minor.yy172,0);}
+#line 2530 "parse.c"
+ break;
+ case 171:
+ case 231:
+#line 600 "parse.y"
{yygotominor.yy174 = sqlite3ExprListAppend(0,yymsp[0].minor.yy172,0);}
-#line 2544 "parse.c"
+#line 2536 "parse.c"
break;
- case 173:
-#line 622 "parse.y"
+ case 174:
+#line 609 "parse.y"
{yygotominor.yy432 = sqlite3IdListAppend(yymsp[-2].minor.yy432,&yymsp[0].minor.yy410);}
-#line 2549 "parse.c"
+#line 2541 "parse.c"
break;
- case 174:
-#line 623 "parse.y"
+ case 175:
+#line 610 "parse.y"
{yygotominor.yy432 = sqlite3IdListAppend(0,&yymsp[0].minor.yy410);}
-#line 2554 "parse.c"
+#line 2546 "parse.c"
break;
- case 176:
-#line 634 "parse.y"
+ case 177:
+#line 621 "parse.y"
{yygotominor.yy172 = yymsp[-1].minor.yy172; sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
-#line 2559 "parse.c"
+#line 2551 "parse.c"
break;
- case 177:
- case 182:
+ case 178:
case 183:
-#line 635 "parse.y"
+ case 184:
+#line 622 "parse.y"
{yygotominor.yy172 = sqlite3Expr(yymsp[0].major, 0, 0, &yymsp[0].minor.yy0);}
-#line 2566 "parse.c"
+#line 2558 "parse.c"
break;
- case 178:
case 179:
-#line 636 "parse.y"
+ case 180:
+#line 623 "parse.y"
{yygotominor.yy172 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
-#line 2572 "parse.c"
+#line 2564 "parse.c"
break;
- case 180:
-#line 638 "parse.y"
+ case 181:
+#line 625 "parse.y"
{
Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy410);
Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[0].minor.yy410);
yygotominor.yy172 = sqlite3Expr(TK_DOT, temp1, temp2, 0);
}
-#line 2581 "parse.c"
+#line 2573 "parse.c"
break;
- case 181:
-#line 643 "parse.y"
+ case 182:
+#line 630 "parse.y"
{
Expr *temp1 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-4].minor.yy410);
Expr *temp2 = sqlite3Expr(TK_ID, 0, 0, &yymsp[-2].minor.yy410);
@@ -2586,32 +2578,32 @@ static void yy_reduce(
Expr *temp4 = sqlite3Expr(TK_DOT, temp2, temp3, 0);
yygotominor.yy172 = sqlite3Expr(TK_DOT, temp1, temp4, 0);
}
-#line 2592 "parse.c"
+#line 2584 "parse.c"
break;
- case 184:
-#line 652 "parse.y"
+ case 185:
+#line 639 "parse.y"
{yygotominor.yy172 = sqlite3RegisterExpr(pParse, &yymsp[0].minor.yy0);}
-#line 2597 "parse.c"
+#line 2589 "parse.c"
break;
- case 185:
-#line 653 "parse.y"
+ case 186:
+#line 640 "parse.y"
{
Token *pToken = &yymsp[0].minor.yy0;
Expr *pExpr = yygotominor.yy172 = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
sqlite3ExprAssignVarNumber(pParse, pExpr);
}
-#line 2606 "parse.c"
+#line 2598 "parse.c"
break;
- case 186:
-#line 659 "parse.y"
+ case 187:
+#line 646 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_CAST, yymsp[-3].minor.yy172, 0, &yymsp[-1].minor.yy410);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
-#line 2614 "parse.c"
+#line 2606 "parse.c"
break;
- case 187:
-#line 664 "parse.y"
+ case 188:
+#line 651 "parse.y"
{
yygotominor.yy172 = sqlite3ExprFunction(yymsp[-1].minor.yy174, &yymsp[-4].minor.yy0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
@@ -2619,27 +2611,29 @@ static void yy_reduce(
yygotominor.yy172->flags |= EP_Distinct;
}
}
-#line 2625 "parse.c"
+#line 2617 "parse.c"
break;
- case 188:
-#line 671 "parse.y"
+ case 189:
+#line 658 "parse.y"
{
yygotominor.yy172 = sqlite3ExprFunction(0, &yymsp[-3].minor.yy0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
-#line 2633 "parse.c"
+#line 2625 "parse.c"
break;
- case 189:
-#line 675 "parse.y"
+ case 190:
+#line 662 "parse.y"
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
yygotominor.yy172 = sqlite3ExprFunction(0,&yymsp[0].minor.yy0);
- if( yygotominor.yy172 ) yygotominor.yy172->op = TK_CONST_FUNC;
+ if( yygotominor.yy172 ){
+ yygotominor.yy172->op = TK_CONST_FUNC;
+ yygotominor.yy172->span = yymsp[0].minor.yy0;
+ }
}
-#line 2643 "parse.c"
+#line 2638 "parse.c"
break;
- case 190:
case 191:
case 192:
case 193:
@@ -2647,24 +2641,25 @@ static void yy_reduce(
case 195:
case 196:
case 197:
-#line 681 "parse.y"
+ case 198:
+#line 671 "parse.y"
{yygotominor.yy172 = sqlite3Expr(yymsp[-1].major, yymsp[-2].minor.yy172, yymsp[0].minor.yy172, 0);}
-#line 2655 "parse.c"
+#line 2650 "parse.c"
break;
- case 198:
- case 200:
-#line 691 "parse.y"
+ case 199:
+ case 201:
+#line 681 "parse.y"
{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 0;}
-#line 2661 "parse.c"
+#line 2656 "parse.c"
break;
- case 199:
- case 201:
-#line 692 "parse.y"
+ case 200:
+ case 202:
+#line 682 "parse.y"
{yygotominor.yy72.eOperator = yymsp[0].minor.yy0; yygotominor.yy72.not = 1;}
-#line 2667 "parse.c"
+#line 2662 "parse.c"
break;
- case 204:
-#line 699 "parse.y"
+ case 205:
+#line 689 "parse.y"
{
ExprList *pList;
pList = sqlite3ExprListAppend(0, yymsp[-1].minor.yy172, 0);
@@ -2677,66 +2672,66 @@ static void yy_reduce(
sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy172->span, &yymsp[-1].minor.yy172->span);
if( yygotominor.yy172 ) yygotominor.yy172->flags |= EP_InfixFunc;
}
-#line 2683 "parse.c"
+#line 2678 "parse.c"
break;
- case 205:
-#line 712 "parse.y"
+ case 206:
+#line 702 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(yymsp[0].major, yymsp[-1].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy172->span,&yymsp[0].minor.yy0);
}
-#line 2691 "parse.c"
+#line 2686 "parse.c"
break;
- case 206:
-#line 716 "parse.y"
+ case 207:
+#line 706 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_ISNULL, yymsp[-2].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
}
-#line 2699 "parse.c"
+#line 2694 "parse.c"
break;
- case 207:
-#line 720 "parse.y"
+ case 208:
+#line 710 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_NOTNULL, yymsp[-2].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy172->span,&yymsp[0].minor.yy0);
}
-#line 2707 "parse.c"
+#line 2702 "parse.c"
break;
- case 208:
-#line 724 "parse.y"
+ case 209:
+#line 714 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_NOTNULL, yymsp[-3].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,&yymsp[0].minor.yy0);
}
-#line 2715 "parse.c"
+#line 2710 "parse.c"
break;
- case 209:
-#line 728 "parse.y"
+ case 210:
+#line 718 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(yymsp[-1].major, yymsp[0].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
}
-#line 2723 "parse.c"
+#line 2718 "parse.c"
break;
- case 210:
-#line 732 "parse.y"
+ case 211:
+#line 722 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_UMINUS, yymsp[0].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
}
-#line 2731 "parse.c"
+#line 2726 "parse.c"
break;
- case 211:
-#line 736 "parse.y"
+ case 212:
+#line 726 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_UPLUS, yymsp[0].minor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy172->span);
}
-#line 2739 "parse.c"
+#line 2734 "parse.c"
break;
- case 214:
-#line 743 "parse.y"
+ case 215:
+#line 733 "parse.y"
{
ExprList *pList = sqlite3ExprListAppend(0, yymsp[-2].minor.yy172, 0);
pList = sqlite3ExprListAppend(pList, yymsp[0].minor.yy172, 0);
@@ -2749,10 +2744,10 @@ static void yy_reduce(
if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy172->span);
}
-#line 2755 "parse.c"
+#line 2750 "parse.c"
break;
- case 217:
-#line 759 "parse.y"
+ case 218:
+#line 749 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy172, 0, 0);
if( yygotominor.yy172 ){
@@ -2763,10 +2758,10 @@ static void yy_reduce(
if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
}
-#line 2769 "parse.c"
+#line 2764 "parse.c"
break;
- case 218:
-#line 769 "parse.y"
+ case 219:
+#line 759 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_SELECT, 0, 0, 0);
if( yygotominor.yy172 ){
@@ -2776,10 +2771,10 @@ static void yy_reduce(
}
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
-#line 2782 "parse.c"
+#line 2777 "parse.c"
break;
- case 219:
-#line 778 "parse.y"
+ case 220:
+#line 768 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-4].minor.yy172, 0, 0);
if( yygotominor.yy172 ){
@@ -2790,10 +2785,10 @@ static void yy_reduce(
if( yymsp[-3].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-4].minor.yy172->span,&yymsp[0].minor.yy0);
}
-#line 2796 "parse.c"
+#line 2791 "parse.c"
break;
- case 220:
-#line 788 "parse.y"
+ case 221:
+#line 778 "parse.y"
{
SrcList *pSrc = sqlite3SrcListAppend(0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);
yygotominor.yy172 = sqlite3Expr(TK_IN, yymsp[-3].minor.yy172, 0, 0);
@@ -2805,10 +2800,10 @@ static void yy_reduce(
if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3Expr(TK_NOT, yygotominor.yy172, 0, 0);
sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy410.z?&yymsp[0].minor.yy410:&yymsp[-1].minor.yy410);
}
-#line 2811 "parse.c"
+#line 2806 "parse.c"
break;
- case 221:
-#line 799 "parse.y"
+ case 222:
+#line 789 "parse.y"
{
Expr *p = yygotominor.yy172 = sqlite3Expr(TK_EXISTS, 0, 0, 0);
if( p ){
@@ -2818,10 +2813,10 @@ static void yy_reduce(
sqlite3SelectDelete(yymsp[-1].minor.yy219);
}
}
-#line 2824 "parse.c"
+#line 2819 "parse.c"
break;
- case 222:
-#line 811 "parse.y"
+ case 223:
+#line 801 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0);
if( yygotominor.yy172 ){
@@ -2831,45 +2826,45 @@ static void yy_reduce(
}
sqlite3ExprSpan(yygotominor.yy172, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
}
-#line 2837 "parse.c"
+#line 2832 "parse.c"
break;
- case 223:
-#line 822 "parse.y"
+ case 224:
+#line 812 "parse.y"
{
yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174, yymsp[-2].minor.yy172, 0);
yygotominor.yy174 = sqlite3ExprListAppend(yygotominor.yy174, yymsp[0].minor.yy172, 0);
}
-#line 2845 "parse.c"
+#line 2840 "parse.c"
break;
- case 224:
-#line 826 "parse.y"
+ case 225:
+#line 816 "parse.y"
{
yygotominor.yy174 = sqlite3ExprListAppend(0, yymsp[-2].minor.yy172, 0);
yygotominor.yy174 = sqlite3ExprListAppend(yygotominor.yy174, yymsp[0].minor.yy172, 0);
}
-#line 2853 "parse.c"
+#line 2848 "parse.c"
break;
- case 233:
-#line 853 "parse.y"
+ case 234:
+#line 843 "parse.y"
{
sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy410, &yymsp[-5].minor.yy410, sqlite3SrcListAppend(0,&yymsp[-3].minor.yy410,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46,
&yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy46);
}
-#line 2861 "parse.c"
+#line 2856 "parse.c"
break;
- case 234:
- case 279:
-#line 859 "parse.y"
+ case 235:
+ case 280:
+#line 849 "parse.y"
{yygotominor.yy46 = OE_Abort;}
-#line 2867 "parse.c"
+#line 2862 "parse.c"
break;
- case 235:
-#line 860 "parse.y"
+ case 236:
+#line 850 "parse.y"
{yygotominor.yy46 = OE_None;}
-#line 2872 "parse.c"
+#line 2867 "parse.c"
break;
- case 238:
-#line 870 "parse.y"
+ case 239:
+#line 860 "parse.y"
{
Expr *p = 0;
if( yymsp[-1].minor.yy410.n>0 ){
@@ -2879,10 +2874,10 @@ static void yy_reduce(
yygotominor.yy174 = sqlite3ExprListAppend(yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy410);
if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
}
-#line 2885 "parse.c"
+#line 2880 "parse.c"
break;
- case 239:
-#line 879 "parse.y"
+ case 240:
+#line 869 "parse.y"
{
Expr *p = 0;
if( yymsp[-1].minor.yy410.n>0 ){
@@ -2892,115 +2887,115 @@ static void yy_reduce(
yygotominor.yy174 = sqlite3ExprListAppend(0, p, &yymsp[-2].minor.yy410);
if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
}
-#line 2898 "parse.c"
+#line 2893 "parse.c"
break;
- case 241:
-#line 893 "parse.y"
+ case 242:
+#line 883 "parse.y"
{sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);}
-#line 2903 "parse.c"
+#line 2898 "parse.c"
break;
- case 242:
case 243:
-#line 897 "parse.y"
+ case 244:
+#line 888 "parse.y"
{sqlite3Vacuum(pParse);}
-#line 2909 "parse.c"
+#line 2904 "parse.c"
break;
- case 244:
- case 246:
-#line 903 "parse.y"
+ case 245:
+ case 247:
+#line 895 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,0);}
-#line 2915 "parse.c"
+#line 2910 "parse.c"
break;
- case 245:
-#line 904 "parse.y"
+ case 246:
+#line 896 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy0,0);}
-#line 2920 "parse.c"
+#line 2915 "parse.c"
break;
- case 247:
-#line 906 "parse.y"
+ case 248:
+#line 898 "parse.y"
{
sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,1);
}
-#line 2927 "parse.c"
+#line 2922 "parse.c"
break;
- case 248:
-#line 909 "parse.y"
+ case 249:
+#line 901 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-1].minor.yy410,0);}
-#line 2932 "parse.c"
+#line 2927 "parse.c"
break;
- case 249:
-#line 910 "parse.y"
+ case 250:
+#line 902 "parse.y"
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,0,0);}
-#line 2937 "parse.c"
+#line 2932 "parse.c"
break;
- case 255:
-#line 922 "parse.y"
+ case 256:
+#line 914 "parse.y"
{
Token all;
all.z = yymsp[-3].minor.yy410.z;
all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy410.z) + yymsp[0].minor.yy0.n;
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all);
}
-#line 2947 "parse.c"
+#line 2942 "parse.c"
break;
- case 256:
-#line 931 "parse.y"
+ case 257:
+#line 923 "parse.y"
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy410, &yymsp[-6].minor.yy410, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[-1].minor.yy46, yymsp[0].minor.yy172, yymsp[-9].minor.yy46);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy410, &yymsp[-6].minor.yy410, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[-1].minor.yy46, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46);
yygotominor.yy410 = (yymsp[-6].minor.yy410.n==0?yymsp[-7].minor.yy410:yymsp[-6].minor.yy410);
}
-#line 2955 "parse.c"
+#line 2950 "parse.c"
break;
- case 257:
- case 260:
-#line 937 "parse.y"
+ case 258:
+ case 261:
+#line 929 "parse.y"
{ yygotominor.yy46 = TK_BEFORE; }
-#line 2961 "parse.c"
+#line 2956 "parse.c"
break;
- case 258:
-#line 938 "parse.y"
+ case 259:
+#line 930 "parse.y"
{ yygotominor.yy46 = TK_AFTER; }
-#line 2966 "parse.c"
+#line 2961 "parse.c"
break;
- case 259:
-#line 939 "parse.y"
+ case 260:
+#line 931 "parse.y"
{ yygotominor.yy46 = TK_INSTEAD;}
-#line 2971 "parse.c"
+#line 2966 "parse.c"
break;
- case 261:
case 262:
-#line 944 "parse.y"
+ case 263:
+#line 936 "parse.y"
{yygotominor.yy370.a = yymsp[0].major; yygotominor.yy370.b = 0;}
-#line 2977 "parse.c"
+#line 2972 "parse.c"
break;
- case 263:
-#line 946 "parse.y"
+ case 264:
+#line 938 "parse.y"
{yygotominor.yy370.a = TK_UPDATE; yygotominor.yy370.b = yymsp[0].minor.yy432;}
-#line 2982 "parse.c"
+#line 2977 "parse.c"
break;
- case 264:
case 265:
-#line 949 "parse.y"
+ case 266:
+#line 941 "parse.y"
{ yygotominor.yy46 = TK_ROW; }
-#line 2988 "parse.c"
+#line 2983 "parse.c"
break;
- case 266:
-#line 951 "parse.y"
+ case 267:
+#line 943 "parse.y"
{ yygotominor.yy46 = TK_STATEMENT; }
-#line 2993 "parse.c"
+#line 2988 "parse.c"
break;
- case 267:
-#line 955 "parse.y"
+ case 268:
+#line 947 "parse.y"
{ yygotominor.yy172 = 0; }
-#line 2998 "parse.c"
+#line 2993 "parse.c"
break;
- case 268:
-#line 956 "parse.y"
+ case 269:
+#line 948 "parse.y"
{ yygotominor.yy172 = yymsp[0].minor.yy172; }
-#line 3003 "parse.c"
+#line 2998 "parse.c"
break;
- case 269:
-#line 960 "parse.y"
+ case 270:
+#line 952 "parse.y"
{
if( yymsp[-2].minor.yy243 ){
yymsp[-2].minor.yy243->pLast->pNext = yymsp[-1].minor.yy243;
@@ -3010,40 +3005,40 @@ static void yy_reduce(
yymsp[-2].minor.yy243->pLast = yymsp[-1].minor.yy243;
yygotominor.yy243 = yymsp[-2].minor.yy243;
}
-#line 3016 "parse.c"
+#line 3011 "parse.c"
break;
- case 270:
-#line 969 "parse.y"
+ case 271:
+#line 961 "parse.y"
{ yygotominor.yy243 = 0; }
-#line 3021 "parse.c"
+#line 3016 "parse.c"
break;
- case 271:
-#line 975 "parse.y"
+ case 272:
+#line 967 "parse.y"
{ yygotominor.yy243 = sqlite3TriggerUpdateStep(&yymsp[-3].minor.yy410, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); }
-#line 3026 "parse.c"
+#line 3021 "parse.c"
break;
- case 272:
-#line 980 "parse.y"
+ case 273:
+#line 972 "parse.y"
{yygotominor.yy243 = sqlite3TriggerInsertStep(&yymsp[-5].minor.yy410, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);}
-#line 3031 "parse.c"
+#line 3026 "parse.c"
break;
- case 273:
-#line 983 "parse.y"
+ case 274:
+#line 975 "parse.y"
{yygotominor.yy243 = sqlite3TriggerInsertStep(&yymsp[-2].minor.yy410, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);}
-#line 3036 "parse.c"
+#line 3031 "parse.c"
break;
- case 274:
-#line 987 "parse.y"
+ case 275:
+#line 979 "parse.y"
{yygotominor.yy243 = sqlite3TriggerDeleteStep(&yymsp[-1].minor.yy410, yymsp[0].minor.yy172);}
-#line 3041 "parse.c"
+#line 3036 "parse.c"
break;
- case 275:
-#line 990 "parse.y"
+ case 276:
+#line 982 "parse.y"
{yygotominor.yy243 = sqlite3TriggerSelectStep(yymsp[0].minor.yy219); }
-#line 3046 "parse.c"
+#line 3041 "parse.c"
break;
- case 276:
-#line 993 "parse.y"
+ case 277:
+#line 985 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_RAISE, 0, 0, 0);
if( yygotominor.yy172 ){
@@ -3051,10 +3046,10 @@ static void yy_reduce(
sqlite3ExprSpan(yygotominor.yy172, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
}
}
-#line 3057 "parse.c"
+#line 3052 "parse.c"
break;
- case 277:
-#line 1000 "parse.y"
+ case 278:
+#line 992 "parse.y"
{
yygotominor.yy172 = sqlite3Expr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy410);
if( yygotominor.yy172 ) {
@@ -3062,119 +3057,119 @@ static void yy_reduce(
sqlite3ExprSpan(yygotominor.yy172, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
}
}
-#line 3068 "parse.c"
+#line 3063 "parse.c"
break;
- case 278:
-#line 1010 "parse.y"
+ case 279:
+#line 1002 "parse.y"
{yygotominor.yy46 = OE_Rollback;}
-#line 3073 "parse.c"
+#line 3068 "parse.c"
break;
- case 280:
-#line 1012 "parse.y"
+ case 281:
+#line 1004 "parse.y"
{yygotominor.yy46 = OE_Fail;}
-#line 3078 "parse.c"
+#line 3073 "parse.c"
break;
- case 281:
-#line 1017 "parse.y"
+ case 282:
+#line 1009 "parse.y"
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy373);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy373,yymsp[-1].minor.yy46);
}
-#line 3085 "parse.c"
+#line 3080 "parse.c"
break;
- case 282:
-#line 1023 "parse.y"
+ case 283:
+#line 1015 "parse.y"
{
sqlite3Attach(pParse, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, yymsp[0].minor.yy386);
}
-#line 3092 "parse.c"
+#line 3087 "parse.c"
break;
- case 283:
-#line 1028 "parse.y"
+ case 284:
+#line 1020 "parse.y"
{ yygotominor.yy386 = 0; }
-#line 3097 "parse.c"
+#line 3092 "parse.c"
break;
- case 284:
-#line 1029 "parse.y"
+ case 285:
+#line 1021 "parse.y"
{ yygotominor.yy386 = yymsp[0].minor.yy172; }
-#line 3102 "parse.c"
+#line 3097 "parse.c"
break;
- case 287:
-#line 1035 "parse.y"
+ case 288:
+#line 1027 "parse.y"
{
sqlite3Detach(pParse, yymsp[0].minor.yy172);
}
-#line 3109 "parse.c"
+#line 3104 "parse.c"
break;
- case 288:
-#line 1041 "parse.y"
+ case 289:
+#line 1033 "parse.y"
{sqlite3Reindex(pParse, 0, 0);}
-#line 3114 "parse.c"
+#line 3109 "parse.c"
break;
- case 289:
-#line 1042 "parse.y"
+ case 290:
+#line 1034 "parse.y"
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
-#line 3119 "parse.c"
+#line 3114 "parse.c"
break;
- case 290:
-#line 1047 "parse.y"
+ case 291:
+#line 1039 "parse.y"
{sqlite3Analyze(pParse, 0, 0);}
-#line 3124 "parse.c"
+#line 3119 "parse.c"
break;
- case 291:
-#line 1048 "parse.y"
+ case 292:
+#line 1040 "parse.y"
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
-#line 3129 "parse.c"
+#line 3124 "parse.c"
break;
- case 292:
-#line 1053 "parse.y"
+ case 293:
+#line 1045 "parse.y"
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy410);
}
-#line 3136 "parse.c"
+#line 3131 "parse.c"
break;
- case 293:
-#line 1056 "parse.y"
+ case 294:
+#line 1048 "parse.y"
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy410);
}
-#line 3143 "parse.c"
+#line 3138 "parse.c"
break;
- case 294:
-#line 1059 "parse.y"
+ case 295:
+#line 1051 "parse.y"
{
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy373);
}
-#line 3150 "parse.c"
+#line 3145 "parse.c"
break;
- case 297:
-#line 1068 "parse.y"
+ case 298:
+#line 1060 "parse.y"
{sqlite3VtabFinishParse(pParse,0);}
-#line 3155 "parse.c"
+#line 3150 "parse.c"
break;
- case 298:
-#line 1069 "parse.y"
+ case 299:
+#line 1061 "parse.y"
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
-#line 3160 "parse.c"
+#line 3155 "parse.c"
break;
- case 299:
-#line 1070 "parse.y"
+ case 300:
+#line 1062 "parse.y"
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, &yymsp[0].minor.yy410);
}
-#line 3167 "parse.c"
+#line 3162 "parse.c"
break;
- case 302:
-#line 1075 "parse.y"
+ case 303:
+#line 1067 "parse.y"
{sqlite3VtabArgInit(pParse);}
-#line 3172 "parse.c"
+#line 3167 "parse.c"
break;
- case 304:
case 305:
case 306:
- case 308:
-#line 1077 "parse.y"
+ case 307:
+ case 309:
+#line 1069 "parse.y"
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
-#line 3180 "parse.c"
+#line 3175 "parse.c"
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
@@ -3241,7 +3236,7 @@ static void yy_syntax_error(
}
pParse->parseError = 1;
}
-#line 3248 "parse.c"
+#line 3243 "parse.c"
sqlite3ParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
}
============================================================
--- sqlite/pragma.c cc12939bb74a6e28eb2e867e75175eecffe089a1
+++ sqlite/pragma.c d0891d3504b6291b506a5ec2226bbf79ffcef003
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
-** $Id: pragma.c,v 1.121 2006/08/08 13:51:43 drh Exp $
+** $Id: pragma.c,v 1.125 2006/11/30 13:06:37 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -482,12 +482,17 @@ void sqlite3Pragma(
sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC);
sqlite3ViewGetColumnNames(pParse, pTab);
for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){
+ const Token *pDflt;
sqlite3VdbeAddOp(v, OP_Integer, i, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0);
sqlite3VdbeOp3(v, OP_String8, 0, 0,
pCol->zType ? pCol->zType : "", 0);
sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0);
- sqlite3ExprCode(pParse, pCol->pDflt);
+ if( pCol->pDflt && (pDflt = &pCol->pDflt->span)->z ){
+ sqlite3VdbeOp3(v, OP_String8, 0, 0, (char*)pDflt->z, pDflt->n);
+ }else{
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
+ }
sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0);
sqlite3VdbeAddOp(v, OP_Callback, 6, 0);
}
@@ -940,6 +945,22 @@ void sqlite3Pragma(
sqlite3_key(db, zRight, strlen(zRight));
}else
#endif
+#if SQLITE_HAS_CODEC || defined(SQLITE_ENABLE_CEROD)
+ if( sqlite3StrICmp(zLeft, "activate_extensions")==0 ){
+#if SQLITE_HAS_CODEC
+ if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){
+ extern void sqlite3_activate_see(const char*);
+ sqlite3_activate_see(&zRight[4]);
+ }
+#endif
+#ifdef SQLITE_ENABLE_CEROD
+ if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
+ extern void sqlite3_activate_cerod(const char*);
+ sqlite3_activate_cerod(&zRight[6]);
+ }
+#endif
+ }
+#endif
{}
============================================================
--- sqlite/prepare.c 84e2c855600c7bfbe2ca691b263301de525f9123
+++ sqlite/prepare.c f4f45b4560defbb566cf8255763625d2c09a8023
@@ -13,7 +13,7 @@
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.38 2006/08/12 13:28:23 drh Exp $
+** $Id: prepare.c,v 1.41 2006/11/09 00:24:54 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -41,28 +41,26 @@ static void corruptSchema(InitData *pDat
** argv[0] = name of thing being created
** argv[1] = root page number for table or index. 0 for trigger or view.
** argv[2] = SQL text for the CREATE statement.
-** argv[3] = "1" for temporary files, "0" for main database, "2" or more
-** for auxiliary database files.
**
*/
int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
InitData *pData = (InitData*)pInit;
sqlite3 *db = pData->db;
- int iDb;
+ int iDb = pData->iDb;
pData->rc = SQLITE_OK;
+ DbClearProperty(db, iDb, DB_Empty);
if( sqlite3MallocFailed() ){
corruptSchema(pData, 0);
return SQLITE_NOMEM;
}
- assert( argc==4 );
+ assert( argc==3 );
if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
- if( argv[1]==0 || argv[3]==0 ){
+ if( argv[1]==0 ){
corruptSchema(pData, 0);
return 1;
}
- iDb = atoi(argv[3]);
assert( iDb>=0 && iDbnDb );
if( argv[2] && argv[2][0] ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
@@ -125,8 +123,7 @@ static int sqlite3InitOne(sqlite3 *db, i
int size;
Table *pTab;
Db *pDb;
- char const *azArg[5];
- char zDbNum[30];
+ char const *azArg[4];
int meta[10];
InitData initData;
char const *zMasterSchema;
@@ -177,12 +174,11 @@ static int sqlite3InitOne(sqlite3 *db, i
azArg[0] = zMasterName;
azArg[1] = "1";
azArg[2] = zMasterSchema;
- sprintf(zDbNum, "%d", iDb);
- azArg[3] = zDbNum;
- azArg[4] = 0;
+ azArg[3] = 0;
initData.db = db;
+ initData.iDb = iDb;
initData.pzErrMsg = pzErrMsg;
- rc = sqlite3InitCallback(&initData, 4, (char **)azArg, 0);
+ rc = sqlite3InitCallback(&initData, 3, (char **)azArg, 0);
if( rc ){
sqlite3SafetyOn(db);
return initData.rc;
@@ -295,8 +291,8 @@ static int sqlite3InitOne(sqlite3 *db, i
}else{
char *zSql;
zSql = sqlite3MPrintf(
- "SELECT name, rootpage, sql, '%s' FROM '%q'.%s",
- zDbNum, db->aDb[iDb].zName, zMasterName);
+ "SELECT name, rootpage, sql FROM '%q'.%s",
+ db->aDb[iDb].zName, zMasterName);
sqlite3SafetyOff(db);
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
if( rc==SQLITE_ABORT ) rc = initData.rc;
@@ -449,12 +445,13 @@ int sqlite3SchemaToIndex(sqlite3 *db, Sc
/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
-int sqlite3_prepare(
+int sqlite3Prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
+ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
- const char** pzTail /* OUT: End of parsed string */
+ const char **pzTail /* OUT: End of parsed string */
){
Parse sParse;
char *zErrMsg = 0;
@@ -507,7 +504,9 @@ int sqlite3_prepare(
if( sqlite3MallocFailed() ){
sParse.rc = SQLITE_NOMEM;
}
- if( pzTail ) *pzTail = sParse.zTail;
+ if( pzTail ){
+ *pzTail = sParse.zTail;
+ }
rc = sParse.rc;
#ifndef SQLITE_OMIT_EXPLAIN
@@ -525,13 +524,16 @@ int sqlite3_prepare(
sqlite3VdbeSetColName(sParse.pVdbe, 3, COLNAME_NAME, "p2", P3_STATIC);
sqlite3VdbeSetColName(sParse.pVdbe, 4, COLNAME_NAME, "p3", P3_STATIC);
}
- }
+ }
#endif
if( sqlite3SafetyOff(db) ){
rc = SQLITE_MISUSE;
}
if( rc==SQLITE_OK ){
+ if( saveSqlFlag ){
+ sqlite3VdbeSetSql(sParse.pVdbe, zSql, sParse.zTail - zSql);
+ }
*ppStmt = (sqlite3_stmt*)sParse.pVdbe;
}else if( sParse.pVdbe ){
sqlite3_finalize((sqlite3_stmt*)sParse.pVdbe);
@@ -546,17 +548,76 @@ int sqlite3_prepare(
rc = sqlite3ApiExit(db, rc);
sqlite3ReleaseThreadData();
+ assert( (rc&db->errMask)==rc );
return rc;
}
+/*
+** Rerun the compilation of a statement after a schema change.
+** Return true if the statement was recompiled successfully.
+** Return false if there is an error of some kind.
+*/
+int sqlite3Reprepare(Vdbe *p){
+ int rc;
+ Vdbe *pNew;
+ const char *zSql;
+ sqlite3 *db;
+
+ zSql = sqlite3VdbeGetSql(p);
+ if( zSql==0 ){
+ return 0;
+ }
+ db = sqlite3VdbeDb(p);
+ rc = sqlite3Prepare(db, zSql, -1, 0, (sqlite3_stmt**)&pNew, 0);
+ if( rc ){
+ assert( pNew==0 );
+ return 0;
+ }else{
+ assert( pNew!=0 );
+ }
+ sqlite3VdbeSwapOps(pNew, p);
+ sqlite3_finalize((sqlite3_stmt*)pNew);
+ return 1;
+}
+
+
+/*
+** Two versions of the official API. Legacy and new use. In the legacy
+** version, the original SQL text is not saved in the prepared statement
+** and so if a schema change occurs, SQLITE_SCHEMA is returned by
+** sqlite3_step(). In the new version, the original SQL text is retained
+** and the statement is automatically recompiled if an schema change
+** occurs.
+*/
+int sqlite3_prepare(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ return sqlite3Prepare(db,zSql,nBytes,0,ppStmt,pzTail);
+}
+int sqlite3_prepare_v2(
+ sqlite3 *db, /* Database handle. */
+ const char *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const char **pzTail /* OUT: End of parsed string */
+){
+ return sqlite3Prepare(db,zSql,nBytes,1,ppStmt,pzTail);
+}
+
+
#ifndef SQLITE_OMIT_UTF16
/*
** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
*/
-int sqlite3_prepare16(
+static int sqlite3Prepare16(
sqlite3 *db, /* Database handle. */
const void *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
+ int saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const void **pzTail /* OUT: End of parsed string */
){
@@ -573,7 +634,7 @@ int sqlite3_prepare16(
}
zSql8 = sqlite3utf16to8(zSql, nBytes);
if( zSql8 ){
- rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);
+ rc = sqlite3Prepare(db, zSql8, -1, saveSqlFlag, ppStmt, &zTail8);
}
if( zTail8 && pzTail ){
@@ -588,4 +649,32 @@ int sqlite3_prepare16(
sqliteFree(zSql8);
return sqlite3ApiExit(db, rc);
}
+
+/*
+** Two versions of the official API. Legacy and new use. In the legacy
+** version, the original SQL text is not saved in the prepared statement
+** and so if a schema change occurs, SQLITE_SCHEMA is returned by
+** sqlite3_step(). In the new version, the original SQL text is retained
+** and the statement is automatically recompiled if an schema change
+** occurs.
+*/
+int sqlite3_prepare16(
+ sqlite3 *db, /* Database handle. */
+ const void *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ return sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail);
+}
+int sqlite3_prepare16_v2(
+ sqlite3 *db, /* Database handle. */
+ const void *zSql, /* UTF-8 encoded SQL statement. */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
+ const void **pzTail /* OUT: End of parsed string */
+){
+ return sqlite3Prepare16(db,zSql,nBytes,1,ppStmt,pzTail);
+}
+
#endif /* SQLITE_OMIT_UTF16 */
============================================================
--- sqlite/select.c 0d4724930a1f34c747105ed1802fa4af0d8eb519
+++ sqlite/select.c 52f09127b53697b1a95835a9b0db9309cca8079f
@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.320 2006/08/11 19:08:27 drh Exp $
+** $Id: select.c,v 1.323 2006/12/16 16:25:15 drh Exp $
*/
#include "sqliteInt.h"
@@ -301,8 +301,8 @@ static int sqliteProcessJoin(Parse *pPar
/* When the NATURAL keyword is present, add WHERE clause terms for
** every column that the two tables have in common.
*/
- if( pLeft->jointype & JT_NATURAL ){
- if( pLeft->pOn || pLeft->pUsing ){
+ if( pRight->jointype & JT_NATURAL ){
+ if( pRight->pOn || pRight->pUsing ){
sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
"an ON or USING clause", 0);
return 1;
@@ -320,7 +320,7 @@ static int sqliteProcessJoin(Parse *pPar
/* Disallow both ON and USING clauses in the same join
*/
- if( pLeft->pOn && pLeft->pUsing ){
+ if( pRight->pOn && pRight->pUsing ){
sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
"clauses in the same join");
return 1;
@@ -329,10 +329,10 @@ static int sqliteProcessJoin(Parse *pPar
/* Add the ON clause to the end of the WHERE clause, connected by
** an AND operator.
*/
- if( pLeft->pOn ){
- setJoinExpr(pLeft->pOn, pRight->iCursor);
- p->pWhere = sqlite3ExprAnd(p->pWhere, pLeft->pOn);
- pLeft->pOn = 0;
+ if( pRight->pOn ){
+ setJoinExpr(pRight->pOn, pRight->iCursor);
+ p->pWhere = sqlite3ExprAnd(p->pWhere, pRight->pOn);
+ pRight->pOn = 0;
}
/* Create extra terms on the WHERE clause for each column named
@@ -342,8 +342,8 @@ static int sqliteProcessJoin(Parse *pPar
** Report an error if any column mentioned in the USING clause is
** not contained in both tables to be joined.
*/
- if( pLeft->pUsing ){
- IdList *pList = pLeft->pUsing;
+ if( pRight->pUsing ){
+ IdList *pList = pRight->pUsing;
for(j=0; jnId; j++){
char *zName = pList->a[j].zName;
if( columnIndex(pLeftTab, zName)<0 || columnIndex(pRightTab, zName)<0 ){
@@ -1071,7 +1071,7 @@ Table *sqlite3ResultSetOfSelect(Parse *p
Expr *p, *pR;
char *zType;
char *zName;
- char *zBasename;
+ int nName;
CollSeq *pColl;
int cnt;
NameContext sNC;
@@ -1104,17 +1104,15 @@ Table *sqlite3ResultSetOfSelect(Parse *p
/* 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;
+ nName = strlen(zName);
for(j=cnt=0; jzName = zName;
/* Get the typename, type affinity, and collating sequence for the
@@ -1311,13 +1309,13 @@ static int prepSelectStmt(Parse *pParse,
if( i>0 ){
struct SrcList_item *pLeft = &pTabList->a[i-1];
- if( (pLeft->jointype & JT_NATURAL)!=0 &&
+ if( (pLeft[1].jointype & JT_NATURAL)!=0 &&
columnIndex(pLeft->pTab, zName)>=0 ){
/* In a NATURAL join, omit the join columns from the
** table on the right */
continue;
}
- if( sqlite3IdListIndex(pLeft->pUsing, zName)>=0 ){
+ if( sqlite3IdListIndex(pLeft[1].pUsing, zName)>=0 ){
/* In a join with a USING clause, omit columns in the
** using clause from the table on the right. */
continue;
@@ -2177,7 +2175,7 @@ static int flattenSubquery(
**
** which is not at all the same thing.
*/
- if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
+ if( pSubSrc->nSrc>1 && (pSubitem->jointype & JT_OUTER)!=0 ){
return 0;
}
@@ -2194,8 +2192,7 @@ static int flattenSubquery(
** But the t2.x>0 test will always fail on a NULL row of t2, which
** effectively converts the OUTER JOIN into an INNER JOIN.
*/
- if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0
- && pSub->pWhere!=0 ){
+ if( (pSubitem->jointype & JT_OUTER)!=0 && pSub->pWhere!=0 ){
return 0;
}
@@ -2234,7 +2231,7 @@ static int flattenSubquery(
pSrc->a[i+iFrom] = pSubSrc->a[i];
memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
}
- pSrc->a[iFrom+nSubSrc-1].jointype = jointype;
+ pSrc->a[iFrom].jointype = jointype;
}
/* Now begin substituting subquery result set expressions for
@@ -2607,7 +2604,14 @@ int sqlite3SelectResolve(
}
}
- return SQLITE_OK;
+ /* If this is one SELECT of a compound, be sure to resolve names
+ ** in the other SELECTs.
+ */
+ if( p->pPrior ){
+ return sqlite3SelectResolve(pParse, p->pPrior, pOuterNC);
+ }else{
+ return SQLITE_OK;
+ }
}
/*
============================================================
--- sqlite/sqlite3.h 63537552e037a5f8771735da3bd49ef03a4aef9a
+++ sqlite/sqlite3.h 9d3ddb04e2bb107eac50266b2dafcf27a03ec5c1
@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.187 2006/07/08 18:09:15 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.195 2006/11/09 00:24:54 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@@ -31,7 +31,7 @@ extern "C" {
#ifdef SQLITE_VERSION
# undef SQLITE_VERSION
#endif
-#define SQLITE_VERSION "3.3.7"
+#define SQLITE_VERSION "3.3.9"
/*
** The format of the version string is "X.Y.Z", where
@@ -48,7 +48,7 @@ extern "C" {
#ifdef SQLITE_VERSION_NUMBER
# undef SQLITE_VERSION_NUMBER
#endif
-#define SQLITE_VERSION_NUMBER 3003007
+#define SQLITE_VERSION_NUMBER 3003009
/*
** The version string is also compiled into the library so that a program
@@ -199,6 +199,44 @@ int sqlite3_exec(
/* end-of-error-codes */
/*
+** Using the sqlite3_extended_result_codes() API, you can cause
+** SQLite to return result codes with additional information in
+** their upper bits. The lower 8 bits will be the same as the
+** primary result codes above. But the upper bits might contain
+** more specific error information.
+**
+** To extract the primary result code from an extended result code,
+** simply mask off the lower 8 bits.
+**
+** primary = extended & 0xff;
+**
+** New result error codes may be added from time to time. Software
+** that uses the extended result codes should plan accordingly and be
+** sure to always handle new unknown codes gracefully.
+**
+** The SQLITE_OK result code will never be extended. It will always
+** be exactly zero.
+**
+** The extended result codes always have the primary result code
+** as a prefix. Primary result codes only contain a single "_"
+** character. Extended result codes contain two or more "_" characters.
+*/
+#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
+#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
+#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
+#define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8))
+#define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8))
+#define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8))
+#define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8))
+#define SQLITE_IOERR_UNLOCK (SQLITE_IOERR | (8<<8))
+#define SQLITE_IOERR_RDLOCK (SQLITE_IOERR | (9<<8))
+
+/*
+** Enable or disable the extended result codes.
+*/
+int sqlite3_extended_result_codes(sqlite3*, int onoff);
+
+/*
** Each entry in an SQLite table has a unique integer key. (The key is
** the value of the INTEGER PRIMARY KEY column if there is such a column,
** otherwise the key is generated at random. The unique key is always
@@ -478,6 +516,7 @@ int sqlite3_set_authorizer(
#define SQLITE_ANALYZE 28 /* Table Name NULL */
#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
+#define SQLITE_FUNCTION 31 /* Function Name NULL */
/*
** The return value of the authorization function should be one of the
@@ -654,6 +693,31 @@ int sqlite3_prepare16(
);
/*
+** Newer versions of the prepare API work just like the legacy versions
+** but with one exception: The a copy of the SQL text is saved in the
+** sqlite3_stmt structure that is returned. If this copy exists, it
+** modifieds the behavior of sqlite3_step() slightly. First, sqlite3_step()
+** will no longer return an SQLITE_SCHEMA error but will instead automatically
+** rerun the compiler to rebuild the prepared statement. Secondly,
+** sqlite3_step() now turns a full result code - the result code that
+** use used to have to call sqlite3_reset() to get.
+*/
+int sqlite3_prepare_v2(
+ sqlite3 *db, /* Database handle */
+ const char *zSql, /* SQL statement, UTF-8 encoded */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const char **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+int sqlite3_prepare16_v2(
+ sqlite3 *db, /* Database handle */
+ const void *zSql, /* SQL statement, UTF-16 encoded */
+ int nBytes, /* Length of zSql in bytes. */
+ sqlite3_stmt **ppStmt, /* OUT: Statement handle */
+ const void **pzTail /* OUT: Pointer to unused portion of zSql */
+);
+
+/*
** Pointers to the following two opaque structures are used to communicate
** with the implementations of user-defined functions.
*/
@@ -1520,6 +1584,42 @@ int sqlite3_enable_load_extension(sqlite
/*
****** EXPERIMENTAL - subject to change without notice **************
**
+** Register an extension entry point that is automatically invoked
+** whenever a new database connection is opened.
+**
+** This API can be invoked at program startup in order to register
+** one or more statically linked extensions that will be available
+** to all new database connections.
+**
+** Duplicate extensions are detected so calling this routine multiple
+** times with the same extension is harmless.
+**
+** This routine stores a pointer to the extension in an array
+** that is obtained from malloc(). If you run a memory leak
+** checker on your program and it reports a leak because of this
+** array, then invoke sqlite3_automatic_extension_reset() prior
+** to shutdown to free the memory.
+**
+** Automatic extensions apply across all threads.
+*/
+int sqlite3_auto_extension(void *xEntryPoint);
+
+
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+**
+** Disable all previously registered automatic extensions. This
+** routine undoes the effect of all prior sqlite3_automatic_extension()
+** calls.
+**
+** This call disabled automatic extensions in all threads.
+*/
+void sqlite3_reset_auto_extension(void);
+
+
+/*
+****** EXPERIMENTAL - subject to change without notice **************
+**
** The interface to the virtual-table mechanism is currently considered
** to be experimental. The interface might change in incompatible ways.
** If this is a problem for you, do not use the interface at this time.
@@ -1544,11 +1644,11 @@ struct sqlite3_module {
struct sqlite3_module {
int iVersion;
int (*xCreate)(sqlite3*, void *pAux,
- int argc, char **argv,
- sqlite3_vtab **ppVTab);
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVTab, char**);
int (*xConnect)(sqlite3*, void *pAux,
- int argc, char **argv,
- sqlite3_vtab **ppVTab);
+ int argc, const char *const*argv,
+ sqlite3_vtab **ppVTab, char**);
int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*);
int (*xDisconnect)(sqlite3_vtab *pVTab);
int (*xDestroy)(sqlite3_vtab *pVTab);
@@ -1668,10 +1768,21 @@ int sqlite3_create_module(
** be taylored to the specific needs of the module implementation. The
** purpose of this superclass is to define certain fields that are common
** to all module implementations.
+**
+** Virtual tables methods can set an error message by assigning a
+** string obtained from sqlite3_mprintf() to zErrMsg. The method should
+** take care that any prior string is freed by a call to sqlite3_free()
+** prior to assigning a new string to zErrMsg. After the error message
+** is delivered up to the client application, the string will be automatically
+** freed by sqlite3_free() and the zErrMsg field will be zeroed. Note
+** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field
+** since virtual tables are commonly implemented in loadable extensions which
+** do not have access to sqlite3MPrintf() or sqlite3Free().
*/
struct sqlite3_vtab {
const sqlite3_module *pModule; /* The module for this virtual table */
int nRef; /* Used internally */
+ char *zErrMsg; /* Error message from sqlite3_mprintf() */
/* Virtual table implementations will typically add additional fields */
};
@@ -1697,6 +1808,24 @@ int sqlite3_declare_vtab(sqlite3*, const
int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
/*
+** Virtual tables can provide alternative implementations of functions
+** using the xFindFunction method. But global versions of those functions
+** must exist in order to be overloaded.
+**
+** This API makes sure a global version of a function with a particular
+** name and number of parameters exists. If no such function exists
+** before this API is called, a new function is created. The implementation
+** of the new function always causes an exception to be thrown. So
+** the new function is not good for anything by itself. Its only
+** purpose is to be a place-holder function that can be overloaded
+** by virtual tables.
+**
+** This API should be considered part of the virtual table interface,
+** which is experimental and subject to change.
+*/
+int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+
+/*
** The interface to the virtual-table mechanism defined above (back up
** to a comment remarkably similar to this one) is currently considered
** to be experimental. The interface might change in incompatible ways.
============================================================
--- sqlite/sqlite3ext.h 5d0b018f61b42caaead89ce1dfa93f5daea29f8c
+++ sqlite/sqlite3ext.h 2c2156cc32a158e2b7bd9042d42accf94bff2e40
@@ -15,7 +15,7 @@
** as extensions by SQLite should #include this file instead of
** sqlite3.h.
**
-** @(#) $Id: sqlite3ext.h,v 1.5 2006/06/27 00:14:28 drh Exp $
+** @(#) $Id: sqlite3ext.h,v 1.7 2006/09/22 23:38:21 shess Exp $
*/
#ifndef _SQLITE3EXT_H_
#define _SQLITE3EXT_H_
@@ -143,6 +143,7 @@ struct sqlite3_api_routines {
const void * (*value_text16le)(sqlite3_value*);
int (*value_type)(sqlite3_value*);
char * (*vmprintf)(const char*,va_list);
+ int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
};
/*
@@ -272,6 +273,7 @@ struct sqlite3_api_routines {
#define sqlite3_value_text16le sqlite3_api->value_text16le
#define sqlite3_value_type sqlite3_api->value_type
#define sqlite3_vmprintf sqlite3_api->vmprintf
+#define sqlite3_overload_function sqlite3_api->overload_function
#endif /* SQLITE_CORE */
#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api;
============================================================
--- sqlite/sqliteInt.h 85975cbb95777f619fd76f1ba728022f13321e1b
+++ sqlite/sqliteInt.h 90dad3c0ba7a5151c48361748ccdada9ff2eff78
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.523 2006/07/26 13:43:31 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.532 2006/12/21 01:29:23 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -447,6 +447,7 @@ struct sqlite3 {
Db *aDb; /* All backends */
int flags; /* Miscellanous flags. See below */
int errCode; /* Most recent error code (SQLITE_*) */
+ int errMask; /* & result codes with this before returning */
u8 autoCommit; /* The auto-commit flag. */
u8 temp_store; /* 1: file 2: memory 0: default */
int nTable; /* Number of tables in the database */
@@ -462,7 +463,7 @@ struct sqlite3 {
u8 busy; /* TRUE if currently initializing */
} init;
int nExtension; /* Number of loaded extensions */
- void *aExtension; /* Array of shared libraray handles */
+ void **aExtension; /* Array of shared libraray handles */
struct Vdbe *pVdbe; /* List of active virtual machines */
int activeVdbeCnt; /* Number of vdbes currently executing */
void (*xTrace)(void*,const char*); /* Trace function */
@@ -1512,6 +1513,7 @@ typedef struct {
*/
typedef struct {
sqlite3 *db; /* The database being initialized */
+ int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */
char **pzErrMsg; /* Error message stored here */
int rc; /* Result code stored here */
} InitData;
@@ -1600,7 +1602,7 @@ void sqlite3EndTable(Parse*,Token*,Token
void sqlite3AddCollateType(Parse*, const char*, int);
void sqlite3EndTable(Parse*,Token*,Token*,Select*);
-void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int);
+void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
int sqlite3ViewGetColumnNames(Parse*,Table*);
@@ -1615,7 +1617,9 @@ SrcList *sqlite3SrcListAppend(SrcList*,
IdList *sqlite3IdListAppend(IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListAppend(SrcList*, Token*, Token*);
-void sqlite3SrcListAddAlias(SrcList*, Token*);
+SrcList *sqlite3SrcListAppendFromTerm(SrcList*, Token*, Token*, Token*,
+ Select*, Expr*, IdList*);
+void sqlite3SrcListShiftJoinType(SrcList*);
void sqlite3SrcListAssignCursors(Parse*, SrcList*);
void sqlite3IdListDelete(IdList*);
void sqlite3SrcListDelete(SrcList*);
@@ -1691,9 +1695,9 @@ void sqlite3ChangeCookie(sqlite3*, Vdbe*
#ifndef SQLITE_OMIT_TRIGGER
void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
- int,Expr*,int);
+ int,Expr*,int, int);
void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*);
- void sqlite3DropTrigger(Parse*, SrcList*);
+ void sqlite3DropTrigger(Parse*, SrcList*, int);
void sqlite3DropTriggerPtr(Parse*, Trigger*);
int sqlite3TriggersExist(Parse*, Table*, int, ExprList*);
int sqlite3CodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
@@ -1821,8 +1825,10 @@ int sqlite3OpenTempDatabase(Parse *);
#ifndef SQLITE_OMIT_LOAD_EXTENSION
void sqlite3CloseExtensions(sqlite3*);
+ int sqlite3AutoLoadExtensions(sqlite3*);
#else
# define sqlite3CloseExtensions(X)
+# define sqlite3AutoLoadExtensions(X) SQLITE_OK
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
@@ -1860,6 +1866,8 @@ int sqlite3OpenTempDatabase(Parse *);
int sqlite3VtabRollback(sqlite3 *db);
int sqlite3VtabCommit(sqlite3 *db);
#endif
+void sqlite3VtabLock(sqlite3_vtab*);
+void sqlite3VtabUnlock(sqlite3_vtab*);
void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
void sqlite3VtabFinishParse(Parse*, Token*);
void sqlite3VtabArgInit(Parse*);
@@ -1869,6 +1877,8 @@ FuncDef *sqlite3VtabOverloadFunction(Fun
int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *);
FuncDef *sqlite3VtabOverloadFunction(FuncDef*, int nArg, Expr*);
+void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**);
+int sqlite3Reprepare(Vdbe*);
#ifdef SQLITE_SSE
#include "sseInt.h"
============================================================
--- sqlite/table.c d8817f43a6c6bf139487db161760b9e1e02da3f1
+++ sqlite/table.c 6d0da66dde26ee75614ed8f584a1996467088d06
@@ -146,7 +146,7 @@ int sqlite3_get_table(
assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
res.azResult[0] = (char*)res.nData;
}
- if( rc==SQLITE_ABORT ){
+ if( (rc&0xff)==SQLITE_ABORT ){
sqlite3_free_table(&res.azResult[1]);
if( res.zErrMsg ){
if( pzErrMsg ){
@@ -156,12 +156,12 @@ int sqlite3_get_table(
sqliteFree(res.zErrMsg);
}
db->errCode = res.rc;
- return res.rc;
+ return res.rc & db->errMask;
}
sqliteFree(res.zErrMsg);
if( rc!=SQLITE_OK ){
sqlite3_free_table(&res.azResult[1]);
- return rc;
+ return rc & db->errMask;
}
if( res.nAlloc>res.nData ){
char **azNew;
@@ -176,7 +176,7 @@ int sqlite3_get_table(
*pazResult = &res.azResult[1];
if( pnColumn ) *pnColumn = res.nColumn;
if( pnRow ) *pnRow = res.nRow;
- return rc;
+ return rc & db->errMask;
}
/*
============================================================
--- sqlite/trigger.c 0fc40125820409a6274834a6e04ad804d96e2793
+++ sqlite/trigger.c 8c55d31876013ed4e97ee7ce24478fbe00db49bb
@@ -49,7 +49,8 @@ void sqlite3BeginTrigger(
SrcList *pTableName,/* The name of the table/view the trigger applies to */
int foreach, /* One of TK_ROW or TK_STATEMENT */
Expr *pWhen, /* WHEN clause */
- int isTemp /* True if the TEMPORARY keyword is present */
+ int isTemp, /* True if the TEMPORARY keyword is present */
+ int noErr /* Suppress errors if the trigger already exists */
){
Trigger *pTrigger = 0;
Table *pTab;
@@ -115,7 +116,9 @@ void sqlite3BeginTrigger(
goto trigger_cleanup;
}
if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash), zName,strlen(zName)) ){
- sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+ if( !noErr ){
+ sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
+ }
goto trigger_cleanup;
}
@@ -439,7 +442,7 @@ void sqlite3DeleteTrigger(Trigger *pTrig
** same job as this routine except it takes a pointer to the trigger
** instead of the trigger name.
**/
-void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
+void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){
Trigger *pTrigger = 0;
int i;
const char *zDb;
@@ -463,7 +466,9 @@ void sqlite3DropTrigger(Parse *pParse, S
if( pTrigger ) break;
}
if( !pTrigger ){
- sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
+ if( !noErr ){
+ sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
+ }
goto drop_trigger_cleanup;
}
sqlite3DropTriggerPtr(pParse, pTrigger);
@@ -663,12 +668,12 @@ static int codeTriggerProgram(
pParse->trigStack->orconf = orconf;
switch( pTriggerStep->op ){
case TK_SELECT: {
- Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);
- assert(ss);
- assert(ss->pSrc);
- sqlite3SelectResolve(pParse, ss, 0);
- sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
- sqlite3SelectDelete(ss);
+ Select *ss = sqlite3SelectDup(pTriggerStep->pSelect);
+ if( ss ){
+ sqlite3SelectResolve(pParse, ss, 0);
+ sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
+ sqlite3SelectDelete(ss);
+ }
break;
}
case TK_UPDATE: {
============================================================
--- sqlite/utf.c 4459801e9b00cfd69993bfca58545d3775682d6e
+++ sqlite/utf.c 67ecb1032bc0b42c105e88d65ef9d9f626eb0e1f
@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.40 2006/07/26 14:57:30 drh Exp $
+** $Id: utf.c,v 1.43 2006/10/19 01:58:44 drh Exp $
**
** Notes on UTF-8:
**
@@ -64,7 +64,7 @@
/*
** This table maps from the first byte of a UTF-8 character to the number
-** of trailing bytes expected. A value '255' indicates that the table key
+** of trailing bytes expected. A value '4' indicates that the table key
** is not a legal first byte for a UTF-8 character.
*/
static const u8 xtra_utf8_bytes[256] = {
@@ -79,10 +79,10 @@ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 10wwwwww */
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
/* 110yyyyy */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -92,7 +92,7 @@ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/* 11110yyy */
-3, 3, 3, 3, 3, 3, 3, 3, 255, 255, 255, 255, 255, 255, 255, 255,
+3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
};
/*
@@ -101,23 +101,39 @@ 3, 3, 3, 3, 3, 3, 3, 3, 255, 255, 25
** read by a naive implementation of a UTF-8 character reader. The code
** in the READ_UTF8 macro explains things best.
*/
-static const int xtra_utf8_bits[4] = {
-0,
-12416, /* (0xC0 << 6) + (0x80) */
-925824, /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
-63447168 /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
+static const int xtra_utf8_bits[] = {
+ 0,
+ 12416, /* (0xC0 << 6) + (0x80) */
+ 925824, /* (0xE0 << 12) + (0x80 << 6) + (0x80) */
+ 63447168 /* (0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
};
+/*
+** If a UTF-8 character contains N bytes extra bytes (N bytes follow
+** the initial byte so that the total character length is N+1) then
+** masking the character with utf8_mask[N] must produce a non-zero
+** result. Otherwise, we have an (illegal) overlong encoding.
+*/
+static const int utf_mask[] = {
+ 0x00000000,
+ 0xffffff80,
+ 0xfffff800,
+ 0xffff0000,
+};
+
#define READ_UTF8(zIn, c) { \
int xtra; \
c = *(zIn)++; \
xtra = xtra_utf8_bytes[c]; \
switch( xtra ){ \
- case 255: c = (int)0xFFFD; break; \
+ case 4: c = (int)0xFFFD; break; \
case 3: c = (c<<6) + *(zIn)++; \
case 2: c = (c<<6) + *(zIn)++; \
case 1: c = (c<<6) + *(zIn)++; \
c -= xtra_utf8_bits[xtra]; \
+ if( (utf_mask[xtra]&c)==0 \
+ || (c&0xFFFFF800)==0xD800 \
+ || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
} \
}
int sqlite3ReadUtf8(const unsigned char *z){
@@ -181,6 +197,7 @@ int sqlite3ReadUtf8(const unsigned char
int c2 = (*zIn++); \
c2 += ((*zIn++)<<8); \
c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
+ if( (c & 0xFFFF0000)==0 ) c = 0xFFFD; \
} \
}
@@ -191,6 +208,7 @@ int sqlite3ReadUtf8(const unsigned char
int c2 = ((*zIn++)<<8); \
c2 += (*zIn++); \
c = (c2&0x03FF) + ((c&0x003F)<<10) + (((c&0x03C0)+0x0040)<<10); \
+ if( (c & 0xFFFF0000)==0 ) c = 0xFFFD; \
} \
}
@@ -245,7 +263,7 @@ int sqlite3VdbeMemTranslate(Mem *pMem, u
unsigned char *zIn; /* Input iterator */
unsigned char *zTerm; /* End of input */
unsigned char *z; /* Output iterator */
- int c;
+ unsigned int c;
assert( pMem->flags&MEM_Str );
assert( pMem->enc!=desiredEnc );
@@ -475,7 +493,7 @@ int sqlite3utf16ByteLen(const void *zIn,
** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
*/
int sqlite3utf16ByteLen(const void *zIn, int nChar){
- int c = 1;
+ unsigned int c = 1;
char const *z = zIn;
int n = 0;
if( SQLITE_UTF16NATIVE==SQLITE_UTF16BE ){
@@ -556,11 +574,11 @@ void sqlite3utfSelfTest(){
** characters in each encoding are inverses of each other.
*/
void sqlite3utfSelfTest(){
- int i;
+ unsigned int i, t;
unsigned char zBuf[20];
unsigned char *z;
int n;
- int c;
+ unsigned int c;
for(i=0; i<0x00110000; i++){
z = zBuf;
@@ -568,7 +586,10 @@ void sqlite3utfSelfTest(){
n = z-zBuf;
z = zBuf;
READ_UTF8(z, c);
- assert( c==i );
+ t = i;
+ if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
+ if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
+ assert( c==t );
assert( (z-zBuf)==n );
}
for(i=0; i<0x00110000; i++){
============================================================
--- sqlite/util.c 5409031819ee4672c5f9c3ac7cf517e267a25845
+++ sqlite/util.c 91d4cb189476906639ae611927d939691d1365f6
@@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.192 2006/07/26 01:39:30 drh Exp $
+** $Id: util.c,v 1.193 2006/09/15 07:28:51 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1446,7 +1446,7 @@ int sqlite3ApiExit(sqlite3* db, int rc){
sqlite3Error(db, SQLITE_NOMEM, 0);
rc = SQLITE_NOMEM;
}
- return rc;
+ return rc & (db ? db->errMask : 0xff);
}
/*
============================================================
--- sqlite/vacuum.c 5b37d0f436f8e1ffacd17934e44720b38d2247f9
+++ sqlite/vacuum.c b4569b08aaa5afb141af3f76d0315745db4e9e4b
@@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
-** $Id: vacuum.c,v 1.59 2006/02/24 02:53:50 drh Exp $
+** $Id: vacuum.c,v 1.66 2007/01/03 23:37:29 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
@@ -22,20 +22,6 @@
#ifndef SQLITE_OMIT_VACUUM
/*
-** Generate a random name of 20 character in length.
-*/
-static void randomName(unsigned char *zBuf){
- static const unsigned char zChars[] =
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789";
- int i;
- sqlite3Randomness(20, zBuf);
- for(i=0; i<20; i++){
- zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
- }
-}
-
-/*
** Execute zSql on database db. Return an error code.
*/
static int execSql(sqlite3 *db, const char *zSql){
@@ -69,8 +55,6 @@ static int execExecSql(sqlite3 *db, cons
return sqlite3_finalize(pStmt);
}
-#endif
-
/*
** The non-standard VACUUM command is used to clean up the database,
** collapse free space, etc. It is modelled after the VACUUM command
@@ -94,61 +78,26 @@ int sqlite3RunVacuum(char **pzErrMsg, sq
*/
int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
int rc = SQLITE_OK; /* Return code from service routines */
-#ifndef SQLITE_OMIT_VACUUM
- const char *zFilename; /* full pathname of the database file */
- int nFilename; /* number of characters in zFilename[] */
- char *zTemp = 0; /* a temporary file in same directory as zFilename */
Btree *pMain; /* The database being vacuumed */
- Btree *pTemp;
- char *zSql = 0;
- int saved_flags; /* Saved value of the db->flags */
- Db *pDb = 0; /* Database to detach at end of vacuum */
+ Btree *pTemp; /* The temporary database we vacuum into */
+ char *zSql = 0; /* SQL statements */
+ int saved_flags; /* Saved value of the db->flags */
+ Db *pDb = 0; /* Database to detach at end of vacuum */
+ char zTemp[SQLITE_TEMPNAME_SIZE+20]; /* Name of the TEMP file */
/* Save the current value of the write-schema flag before setting it. */
saved_flags = db->flags;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+ sqlite3OsTempFileName(zTemp);
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction",
(char*)0);
rc = SQLITE_ERROR;
goto end_of_vacuum;
}
-
- /* Get the full pathname of the database file and create a
- ** temporary filename in the same directory as the original file.
- */
pMain = db->aDb[0].pBt;
- zFilename = sqlite3BtreeGetFilename(pMain);
- assert( zFilename );
- if( zFilename[0]=='\0' ){
- /* The in-memory database. Do nothing. Return directly to avoid causing
- ** an error trying to DETACH the vacuum_db (which never got attached)
- ** in the exit-handler.
- */
- return SQLITE_OK;
- }
- nFilename = strlen(zFilename);
- zTemp = sqliteMalloc( nFilename+100 );
- if( zTemp==0 ){
- rc = SQLITE_NOMEM;
- goto end_of_vacuum;
- }
- strcpy(zTemp, zFilename);
- /* The randomName() procedure in the following loop uses an excellent
- ** source of randomness to generate a name from a space of 1.3e+31
- ** possibilities. So unless the directory already contains on the order
- ** of 1.3e+31 files, the probability that the following loop will
- ** run more than once or twice is vanishingly small. We are certain
- ** enough that this loop will always terminate (and terminate quickly)
- ** that we don't even bother to set a maximum loop count.
- */
- do {
- zTemp[nFilename] = '-';
- randomName((unsigned char*)&zTemp[nFilename+1]);
- } while( sqlite3OsFileExists(zTemp) );
-
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
** can be set to 'off' for this file, as it is not recovered if a crash
** occurs anyway. The integrity of the database is maintained by a
@@ -190,7 +139,9 @@ int sqlite3RunVacuum(char **pzErrMsg, sq
*/
rc = execExecSql(db,
"SELECT 'CREATE TABLE vacuum_db.' || substr(sql,14,100000000) "
- " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'");
+ " FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence'"
+ " AND rootpage>0"
+ );
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execExecSql(db,
"SELECT 'CREATE INDEX vacuum_db.' || substr(sql,14,100000000)"
@@ -200,11 +151,6 @@ int sqlite3RunVacuum(char **pzErrMsg, sq
"SELECT 'CREATE UNIQUE INDEX vacuum_db.' || substr(sql,21,100000000) "
" FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %'");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- rc = execExecSql(db,
- "SELECT 'CREATE VIEW vacuum_db.' || substr(sql,13,100000000) "
- " FROM sqlite_master WHERE type='view'"
- );
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM xxx;" to copy
@@ -214,7 +160,9 @@ int sqlite3RunVacuum(char **pzErrMsg, sq
"SELECT 'INSERT INTO vacuum_db.' || quote(name) "
"|| ' SELECT * FROM ' || quote(name) || ';'"
"FROM sqlite_master "
- "WHERE type = 'table' AND name!='sqlite_sequence';"
+ "WHERE type = 'table' AND name!='sqlite_sequence' "
+ " AND rootpage>0"
+
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
@@ -233,18 +181,20 @@ int sqlite3RunVacuum(char **pzErrMsg, sq
if( rc!=SQLITE_OK ) goto end_of_vacuum;
- /* Copy the triggers from the main database to the temporary database.
- ** This was deferred before in case the triggers interfered with copying
- ** the data. It's possible the indices should be deferred until this
- ** point also.
+ /* Copy the triggers, views, and virtual tables from the main database
+ ** over to the temporary database. None of these objects has any
+ ** associated storage, so all we have to do is copy their entries
+ ** from the SQLITE_MASTER table.
*/
- rc = execExecSql(db,
- "SELECT 'CREATE TRIGGER vacuum_db.' || substr(sql, 16, 1000000) "
- "FROM sqlite_master WHERE type='trigger'"
+ rc = execSql(db,
+ "INSERT INTO vacuum_db.sqlite_master "
+ " SELECT type, name, tbl_name, rootpage, sql"
+ " FROM sqlite_master"
+ " WHERE type='view' OR type='trigger'"
+ " OR (type='table' AND rootpage=0)"
);
- if( rc!=SQLITE_OK ) goto end_of_vacuum;
+ if( rc ) goto end_of_vacuum;
-
/* At this point, unless the main db was completely empty, there is now a
** transaction open on the vacuum database, but not on the main database.
** Open a btree level transaction on the main database. This allows a
@@ -309,21 +259,12 @@ end_of_vacuum:
pDb->pSchema = 0;
}
- /* If one of the execSql() calls above returned SQLITE_NOMEM, then the
- ** mallocFailed flag will be clear (because execSql() calls sqlite3_exec()).
- ** Fix this so the flag and return code match.
- */
- if( rc==SQLITE_NOMEM ){
- sqlite3MallocFailed();
- }
-
- if( zTemp ){
- sqlite3OsDelete(zTemp);
- sqliteFree(zTemp);
- }
+ sqlite3OsDelete(zTemp);
+ strcat(zTemp, "-journal");
+ sqlite3OsDelete(zTemp);
sqliteFree( zSql );
sqlite3ResetInternalSchema(db, 0);
-#endif
return rc;
}
+#endif /* SQLITE_OMIT_VACUUM */
============================================================
--- sqlite/vdbe.c 3cea0b930abca02facd4c01fc6f369015730a926
+++ sqlite/vdbe.c 180ea84f8087d4b56ccc4c4d496d4558cfaf4450
@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.573 2006/08/08 13:51:43 drh Exp $
+** $Id: vdbe.c,v 1.583 2007/01/04 01:20:11 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1812,32 +1812,31 @@ case OP_IfNot: { /* no-push *
/* Opcode: IsNull P1 P2 *
**
-** If any of the top abs(P1) values on the stack are NULL, then jump
-** to P2. Pop the stack P1 times if P1>0. If P1<0 leave the stack
-** unchanged.
+** Check the top of the stack and jump to P2 if the top of the stack
+** is NULL. If P1 is positive, then pop P1 elements from the stack
+** regardless of whether or not the jump is taken. If P1 is negative,
+** pop -P1 elements from the stack only if the jump is taken and leave
+** the stack unchanged if the jump is not taken.
*/
case OP_IsNull: { /* same as TK_ISNULL, no-push */
- int i, cnt;
- Mem *pTerm;
- cnt = pOp->p1;
- if( cnt<0 ) cnt = -cnt;
- pTerm = &pTos[1-cnt];
- assert( pTerm>=p->aStack );
- for(i=0; iflags & MEM_Null ){
- pc = pOp->p2-1;
- break;
+ if( pTos->flags & MEM_Null ){
+ pc = pOp->p2-1;
+ if( pOp->p1<0 ){
+ popStack(&pTos, -pOp->p1);
}
}
- if( pOp->p1>0 ) popStack(&pTos, cnt);
+ if( pOp->p1>0 ){
+ popStack(&pTos, pOp->p1);
+ }
break;
}
/* Opcode: NotNull P1 P2 *
**
-** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the
-** stack if P1 times if P1 is greater than zero. If P1 is less than
-** zero then leave the stack unchanged.
+** Jump to P2 if the top abs(P1) values on the stack are all not NULL.
+** Regardless of whether or not the jump is taken, pop the stack
+** P1 times if P1 is greater than zero. But if P1 is negative,
+** leave the stack unchanged.
*/
case OP_NotNull: { /* same as TK_NOTNULL, no-push */
int i, cnt;
@@ -2010,7 +2009,9 @@ case OP_Column: {
pC->aRow = 0;
}
}
- assert( zRec!=0 || avail>=payloadSize || avail>=9 );
+ /* The following assert is true in all cases accept when
+ ** the database file has been corrupted externally.
+ ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
szHdrSz = GetVarint((u8*)zData, offset);
/* The KeyFetch() or DataFetch() above are fast and will get the entire
@@ -2980,7 +2981,7 @@ case OP_IsUnique: { /* no-push */
R = pTos->i;
assert( (pTos->flags & MEM_Dyn)==0 );
pTos--;
- assert( i>=0 && i<=p->nCursor );
+ assert( i>=0 && inCursor );
pCx = p->apCsr[i];
assert( pCx!=0 );
pCrsr = pCx->pCursor;
@@ -3081,6 +3082,9 @@ case OP_NotExists: { /* no-push *
pC->rowidIsValid = res==0;
pC->nullRow = 0;
pC->cacheStatus = CACHE_STALE;
+ /* res might be uninitialized if rc!=SQLITE_OK. But if rc!=SQLITE_OK
+ ** processing is about to abort so we really do not care whether or not
+ ** the following jump is taken. */
if( res!=0 ){
pc = pOp->p2 - 1;
pC->rowidIsValid = 0;
@@ -3852,38 +3856,6 @@ case OP_IdxGE: { /* no-push */
break;
}
-/* Opcode: IdxIsNull P1 P2 *
-**
-** The top of the stack contains an index entry such as might be generated
-** by the MakeIdxRec opcode. This routine looks at the first P1 fields of
-** that key. If any of the first P1 fields are NULL, then a jump is made
-** to address P2. Otherwise we fall straight through.
-**
-** The index entry is always popped from the stack.
-*/
-case OP_IdxIsNull: { /* no-push */
- int i = pOp->p1;
- int k, n;
- const char *z;
- u32 serial_type;
-
- assert( pTos>=p->aStack );
- assert( pTos->flags & MEM_Blob );
- z = pTos->z;
- n = pTos->n;
- k = sqlite3GetVarint32((u8*)z, &serial_type);
- for(; k0; i--){
- k += sqlite3GetVarint32((u8*)&z[k], &serial_type);
- if( serial_type==0 ){ /* Serial type 0 is a NULL */
- pc = pOp->p2-1;
- break;
- }
- }
- Release(pTos);
- pTos--;
- break;
-}
-
/* Opcode: Destroy P1 P2 *
**
** Delete an entire database table or index whose root page in the database
@@ -4050,10 +4022,11 @@ case OP_ParseSchema: { /* no-push
if( !DbHasProperty(db, iDb, DB_SchemaLoaded) ) break;
zMaster = SCHEMA_TABLE(iDb);
initData.db = db;
+ initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
zSql = sqlite3MPrintf(
- "SELECT name, rootpage, sql, %d FROM '%q'.%s WHERE %s",
- pOp->p1, db->aDb[iDb].zName, zMaster, pOp->p3);
+ "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s",
+ db->aDb[iDb].zName, zMaster, pOp->p3);
if( zSql==0 ) goto no_mem;
sqlite3SafetyOff(db);
assert( db->init.busy==0 );
@@ -4499,6 +4472,7 @@ case OP_AggFinal: { /* no-push */
}
+#ifndef SQLITE_OMIT_VACUUM
/* Opcode: Vacuum * * *
**
** Vacuum the entire database. This opcode will cause other virtual
@@ -4511,6 +4485,7 @@ case OP_Vacuum: { /* no-push */
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
break;
}
+#endif
/* Opcode: Expire P1 * *
**
@@ -4672,9 +4647,9 @@ case OP_VFilter: { /* no-push */
assert( (pTos[0].flags&MEM_Int)!=0 && pTos[-1].flags==MEM_Int );
nArg = pTos[-1].i;
- /* Invoke the xFilter method if one is defined. */
- if( pModule->xFilter ){
- int res;
+ /* Invoke the xFilter method */
+ {
+ int res = 0;
int i;
Mem **apArg = p->apArg;
for(i = 0; ixUpdate(pVtab, nArg, apArg, &rowid);
+ sqlite3VtabUnlock(pVtab);
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
if( pOp->p1 && rc==SQLITE_OK ){
assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
============================================================
--- sqlite/vdbe.h 258b5d1c0aaa72192f09ff0568ce42b383f156fa
+++ sqlite/vdbe.h 9720cae673359dc2bdcb106285ecf686b7d3ef24
@@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
-** $Id: vdbe.h,v 1.105 2006/06/13 23:51:35 drh Exp $
+** $Id: vdbe.h,v 1.106 2006/11/09 00:24:54 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
@@ -135,6 +135,9 @@ sqlite3 *sqlite3VdbeDb(Vdbe*);
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
void sqlite3VdbeCountChanges(Vdbe*);
sqlite3 *sqlite3VdbeDb(Vdbe*);
+void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
+const char *sqlite3VdbeGetSql(Vdbe*);
+void sqlite3VdbeSwapOps(Vdbe*,Vdbe*);
#ifndef NDEBUG
void sqlite3VdbeComment(Vdbe*, const char*, ...);
============================================================
--- sqlite/vdbeInt.h e3eaab262b67b84474625cfc38aec1125c32834b
+++ sqlite/vdbeInt.h 1ca07f2d7446c90230346aed7fbf990c032460bc
@@ -328,6 +328,8 @@ struct Vdbe {
u8 inVtabMethod; /* See comments above */
int nChange; /* Number of db changes made since last reset */
i64 startTime; /* Time when query started - used for profiling */
+ int nSql; /* Number of bytes in zSql */
+ char *zSql; /* Text of the SQL statement that generated this */
#ifdef SQLITE_SSE
int fetchId; /* Statement number used by sqlite3_fetch_statement */
int lru; /* Counter used for LRU cache replacement */
============================================================
--- sqlite/vdbeapi.c 81f531d7dc5c898131b02ef85f6c6144ab2892cf
+++ sqlite/vdbeapi.c 2d1e6843af8705a1172e54a418d2a3d5febd1dd7
@@ -153,9 +153,13 @@ void sqlite3_result_value(sqlite3_contex
/*
** Execute the statement pStmt, either until a row of data is ready, the
** statement is completely executed or an error occurs.
+**
+** This routine implements the bulk of the logic behind the sqlite_step()
+** API. The only thing omitted is the automatic recompile if a
+** schema change has occurred. That detail is handled by the
+** outer sqlite3_step() wrapper procedure.
*/
-int sqlite3_step(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe*)pStmt;
+static int sqlite3Step(Vdbe *p){
sqlite3 *db;
int rc;
@@ -172,7 +176,8 @@ int sqlite3_step(sqlite3_stmt *pStmt){
if( p->rc==SQLITE_OK ){
p->rc = SQLITE_SCHEMA;
}
- return SQLITE_ERROR;
+ rc = SQLITE_ERROR;
+ goto end_of_step;
}
db = p->db;
if( sqlite3SafetyOn(db) ){
@@ -254,8 +259,42 @@ int sqlite3_step(sqlite3_stmt *pStmt){
sqlite3Error(p->db, rc, 0);
p->rc = sqlite3ApiExit(p->db, p->rc);
+end_of_step:
+ assert( (rc&0xff)==rc );
+ if( p->zSql && (rc&0xff)rc;
+ }else{
+ /* This is for legacy sqlite3_prepare() builds and when the code
+ ** is SQLITE_ROW or SQLITE_DONE */
+ return rc;
+ }
+}
+
+/*
+** This is the top-level implementation of sqlite3_step(). Call
+** sqlite3Step() to do most of the work. If a schema error occurs,
+** call sqlite3Reprepare() and try again.
+*/
+#ifdef SQLITE_OMIT_PARSER
+int sqlite3_step(sqlite3_stmt *pStmt){
+ return sqlite3Step((Vdbe*)pStmt);
+}
+#else
+int sqlite3_step(sqlite3_stmt *pStmt){
+ int cnt = 0;
+ int rc;
+ Vdbe *v = (Vdbe*)pStmt;
+ while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
+ && cnt++ < 5
+ && sqlite3Reprepare(v) ){
+ sqlite3_reset(pStmt);
+ v->expired = 0;
+ }
return rc;
}
+#endif
/*
** Extract the user data from a sqlite3_context structure and return a
@@ -267,6 +306,27 @@ void *sqlite3_user_data(sqlite3_context
}
/*
+** The following is the implementation of an SQL function that always
+** fails with an error message stating that the function is used in the
+** wrong context. The sqlite3_overload_function() API might construct
+** SQL function that use this routine so that the functions will exist
+** for name resolution but are actually overloaded by the xFindFunction
+** method of virtual tables.
+*/
+void sqlite3InvalidFunction(
+ sqlite3_context *context, /* The function calling context */
+ int argc, /* Number of arguments to the function */
+ sqlite3_value **argv /* Value of each argument */
+){
+ const char *zName = context->pFunc->zName;
+ char *zErr;
+ zErr = sqlite3MPrintf(
+ "unable to use function %s in the requested context", zName);
+ sqlite3_result_error(context, zErr, -1);
+ sqliteFree(zErr);
+}
+
+/*
** Allocate or return the aggregate context for a user function. A new
** context is allocated on the first call. Subsequent calls return the
** same context that was returned on prior calls.
@@ -815,6 +875,7 @@ int sqlite3_transfer_bindings(sqlite3_st
rc = sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]);
sqlite3MallocAllow();
}
+ assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
return rc;
}
============================================================
--- sqlite/vdbeaux.c d56304b50c912faefd9f88dff621391310ed2fc5
+++ sqlite/vdbeaux.c 05cc6f0f82b86dfb4c356e06ab07ec8cc83a2eda
@@ -49,6 +49,38 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){
}
/*
+** Remember the SQL string for a prepared statement.
+*/
+void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n){
+ if( p==0 ) return;
+ assert( p->zSql==0 );
+ p->zSql = sqlite3StrNDup(z, n);
+}
+
+/*
+** Return the SQL associated with a prepared statement
+*/
+const char *sqlite3VdbeGetSql(Vdbe *p){
+ return p->zSql;
+}
+
+/*
+** Swap the set of Opcodes between to Vdbe structures. No
+** other parts of either Vdbe structure are changed.
+*/
+void sqlite3VdbeSwapOps(Vdbe *pA, Vdbe *pB){
+ Op *aOp;
+ int nOp;
+
+ aOp = pA->aOp;
+ nOp = pA->nOp;
+ pA->aOp = pB->aOp;
+ pA->nOp = pB->nOp;
+ pB->aOp = aOp;
+ pB->nOp = nOp;
+}
+
+/*
** Turn tracing on or off
*/
void sqlite3VdbeTrace(Vdbe *p, FILE *trace){
@@ -1145,7 +1177,9 @@ static int vdbeCommit(sqlite3 *db){
** transaction files are deleted.
*/
rc = sqlite3OsDelete(zMaster);
- assert( rc==SQLITE_OK );
+ if( rc ){
+ return rc;
+ }
sqliteFree(zMaster);
zMaster = 0;
rc = sqlite3OsSyncDirectory(zMainFile);
@@ -1287,9 +1321,10 @@ int sqlite3VdbeHalt(Vdbe *p){
/* No commit or rollback needed if the program never started */
if( p->pc>=0 ){
-
+ int mrc; /* Primary error code from p->rc */
/* Check for one of the special errors - SQLITE_NOMEM or SQLITE_IOERR */
- isSpecialError = ((p->rc==SQLITE_NOMEM || p->rc==SQLITE_IOERR)?1:0);
+ mrc = p->rc & 0xff;
+ isSpecialError = ((mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR)?1:0);
if( isSpecialError ){
/* This loop does static analysis of the query to see which of the
** following three categories it falls into:
@@ -1433,18 +1468,20 @@ int sqlite3VdbeReset(Vdbe *p){
** VDBE_MAGIC_INIT.
*/
int sqlite3VdbeReset(Vdbe *p){
+ sqlite3 *db;
if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
sqlite3Error(p->db, SQLITE_MISUSE, 0);
return SQLITE_MISUSE;
}
+ db = p->db;
/* If the VM did not run to completion or if it encountered an
** error, then it might not have been halted properly. So halt
** it now.
*/
- sqlite3SafetyOn(p->db);
+ sqlite3SafetyOn(db);
sqlite3VdbeHalt(p);
- sqlite3SafetyOff(p->db);
+ sqlite3SafetyOff(db);
/* If the VDBE has be run even partially, then transfer the error code
** and error message from the VDBE into the main database structure. But
@@ -1453,21 +1490,20 @@ int sqlite3VdbeReset(Vdbe *p){
*/
if( p->pc>=0 ){
if( p->zErrMsg ){
- sqlite3* db = p->db;
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, sqlite3FreeX);
db->errCode = p->rc;
p->zErrMsg = 0;
}else if( p->rc ){
- sqlite3Error(p->db, p->rc, 0);
+ sqlite3Error(db, p->rc, 0);
}else{
- sqlite3Error(p->db, SQLITE_OK, 0);
+ sqlite3Error(db, SQLITE_OK, 0);
}
}else if( p->rc && p->expired ){
/* The expired flag was set on the VDBE before the first call
** to sqlite3_step(). For consistency (since sqlite3_step() was
** called), set the database error in this case as well.
*/
- sqlite3Error(p->db, p->rc, 0);
+ sqlite3Error(db, p->rc, 0);
}
/* Reclaim all memory used by the VDBE
@@ -1502,9 +1538,9 @@ int sqlite3VdbeReset(Vdbe *p){
p->magic = VDBE_MAGIC_INIT;
p->aborted = 0;
if( p->rc==SQLITE_SCHEMA ){
- sqlite3ResetInternalSchema(p->db, 0);
+ sqlite3ResetInternalSchema(db, 0);
}
- return p->rc;
+ return p->rc & db->errMask;
}
/*
@@ -1515,6 +1551,7 @@ int sqlite3VdbeFinalize(Vdbe *p){
int rc = SQLITE_OK;
if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){
rc = sqlite3VdbeReset(p);
+ assert( (rc & p->db->errMask)==rc );
}else if( p->magic!=VDBE_MAGIC_INIT ){
return SQLITE_MISUSE;
}
@@ -1569,6 +1606,7 @@ void sqlite3VdbeDelete(Vdbe *p){
sqliteFree(p->aStack);
releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
sqliteFree(p->aColName);
+ sqliteFree(p->zSql);
p->magic = VDBE_MAGIC_DEAD;
sqliteFree(p);
}
@@ -1581,7 +1619,9 @@ int sqlite3VdbeCursorMoveto(Cursor *p){
int sqlite3VdbeCursorMoveto(Cursor *p){
if( p->deferredMoveto ){
int res, rc;
+#ifdef SQLITE_TEST
extern int sqlite3_search_count;
+#endif
assert( p->isTable );
if( p->isTable ){
rc = sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
@@ -1885,14 +1925,13 @@ int sqlite3VdbeRecordCompare(
idx2 += GetVarint( aKey2+idx2, serial_type2 );
if( d2>=nKey2 && sqlite3VdbeSerialTypeLen(serial_type2)>0 ) break;
- /* Assert that there is enough space left in each key for the blob of
- ** data to go with the serial type just read. This assert may fail if
- ** the file is corrupted. Then read the value from each key into mem1
- ** and mem2 respectively.
+ /* Extract the values to be compared.
*/
d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
d2 += sqlite3VdbeSerialGet(&aKey2[d2], serial_type2, &mem2);
+ /* Do the comparison
+ */
rc = sqlite3MemCompare(&mem1, &mem2, iaColl[i] : 0);
if( mem1.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
if( mem2.flags & MEM_Dyn ) sqlite3VdbeMemRelease(&mem2);
============================================================
--- sqlite/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3
+++ sqlite/vdbemem.c 26623176bf1c616aa478da958fac49502491a921
@@ -50,14 +50,6 @@ int sqlite3VdbeChangeEncoding(Mem *pMem,
assert(rc==SQLITE_OK || rc==SQLITE_NOMEM);
assert(rc==SQLITE_OK || pMem->enc!=desiredEnc);
assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc);
-
- if( rc==SQLITE_NOMEM ){
-/*
- sqlite3VdbeMemRelease(pMem);
- pMem->flags = MEM_Null;
- pMem->z = 0;
-*/
- }
return rc;
#endif
}
@@ -127,22 +119,9 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem
** Make sure the given Mem is \u0000 terminated.
*/
int sqlite3VdbeMemNulTerminate(Mem *pMem){
- /* In SQLite, a string without a nul terminator occurs when a string
- ** is loaded from disk (in this case the memory management is ephemeral),
- ** or when it is supplied by the user as a bound variable or function
- ** return value. Therefore, the memory management of the string must be
- ** either ephemeral, static or controlled by a user-supplied destructor.
- */
- assert(
- !(pMem->flags&MEM_Str) || /* it's not a string, or */
- (pMem->flags&MEM_Term) || /* it's nul term. already, or */
- (pMem->flags&(MEM_Ephem|MEM_Static)) || /* it's static or ephem, or */
- (pMem->flags&MEM_Dyn && pMem->xDel) /* external management */
- );
if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
return SQLITE_OK; /* Nothing to do */
}
-
if( pMem->flags & (MEM_Static|MEM_Ephem) ){
return sqlite3VdbeMemMakeWriteable(pMem);
}else{
@@ -151,7 +130,11 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem
memcpy(z, pMem->z, pMem->n);
z[pMem->n] = 0;
z[pMem->n+1] = 0;
- pMem->xDel(pMem->z);
+ if( pMem->xDel ){
+ pMem->xDel(pMem->z);
+ }else{
+ sqliteFree(pMem->z);
+ }
pMem->xDel = 0;
pMem->z = z;
}
@@ -782,7 +765,9 @@ const void *sqlite3ValueText(sqlite3_val
return 0;
}
}
- }else if( !(pVal->flags&MEM_Blob) ){
+ sqlite3VdbeMemNulTerminate(pVal);
+ }else{
+ assert( (pVal->flags&MEM_Blob)==0 );
sqlite3VdbeMemStringify(pVal, enc);
assert( 0==(1&(int)pVal->z) );
}
============================================================
--- sqlite/vtab.c cae036dc7b0b7d7f5f17eef646b1d53940a21572
+++ sqlite/vtab.c aa30e940058ea56a1b7a9a7019ec21d307316fb4
@@ -11,7 +11,7 @@
*************************************************************************
** This file contains code used to help implement virtual tables.
**
-** $Id: vtab.c,v 1.29 2006/07/26 16:22:15 danielk1977 Exp $
+** $Id: vtab.c,v 1.37 2006/09/18 20:24:03 drh Exp $
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"
@@ -41,6 +41,29 @@ int sqlite3_create_module(
}
/*
+** Lock the virtual table so that it cannot be disconnected.
+** Locks nest. Every lock should have a corresponding unlock.
+** If an unlock is omitted, resources leaks will occur.
+**
+** If a disconnect is attempted while a virtual table is locked,
+** the disconnect is deferred until all locks have been removed.
+*/
+void sqlite3VtabLock(sqlite3_vtab *pVtab){
+ pVtab->nRef++;
+}
+
+/*
+** Unlock a virtual table. When the last lock is removed,
+** disconnect the virtual table.
+*/
+void sqlite3VtabUnlock(sqlite3_vtab *pVtab){
+ pVtab->nRef--;
+ if( pVtab->nRef==0 ){
+ pVtab->pModule->xDisconnect(pVtab);
+ }
+}
+
+/*
** Clear any and all virtual-table information from the Table record.
** This routine is called, for example, just before deleting the Table
** record.
@@ -49,10 +72,7 @@ void sqlite3VtabClear(Table *p){
sqlite3_vtab *pVtab = p->pVtab;
if( pVtab ){
assert( p->pMod && p->pMod->pModule );
- pVtab->nRef--;
- if( pVtab->nRef==0 ){
- pVtab->pModule->xDisconnect(pVtab);
- }
+ sqlite3VtabUnlock(pVtab);
p->pVtab = 0;
}
if( p->azModuleArg ){
@@ -139,7 +159,7 @@ static void addArgumentToVtab(Parse *pPa
*/
static void addArgumentToVtab(Parse *pParse){
if( pParse->sArg.z && pParse->pNewTable ){
- const char *z = pParse->sArg.z;
+ const char *z = (const char*)pParse->sArg.z;
int n = pParse->sArg.n;
addModuleArgument(pParse->pNewTable, sqliteStrNDup(z, n));
}
@@ -266,14 +286,16 @@ static int vtabCallConstructor(
sqlite3 *db,
Table *pTab,
Module *pMod,
- int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **),
+ int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
int rc;
int rc2;
- char **azArg = pTab->azModuleArg;
+ sqlite3_vtab *pVtab;
+ const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
- char *zErr = sqlite3MPrintf("vtable constructor failed: %s", pTab->zName);
+ char *zErr = 0;
+ char *zModuleName = sqlite3MPrintf("%s", pTab->zName);
assert( !db->pVTab );
assert( xConstruct );
@@ -281,17 +303,22 @@ static int vtabCallConstructor(
db->pVTab = pTab;
rc = sqlite3SafetyOff(db);
assert( rc==SQLITE_OK );
- rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab);
+ rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab, &zErr);
rc2 = sqlite3SafetyOn(db);
- if( rc==SQLITE_OK && pTab->pVtab ){
- pTab->pVtab->pModule = pMod->pModule;
- pTab->pVtab->nRef = 1;
+ pVtab = pTab->pVtab;
+ if( rc==SQLITE_OK && pVtab ){
+ pVtab->pModule = pMod->pModule;
+ pVtab->nRef = 1;
}
if( SQLITE_OK!=rc ){
- *pzErr = zErr;
- zErr = 0;
- } else if( db->pVTab ){
+ if( zErr==0 ){
+ *pzErr = sqlite3MPrintf("vtable constructor failed: %s", zModuleName);
+ }else {
+ *pzErr = sqlite3MPrintf("%s", zErr);
+ sqlite3_free(zErr);
+ }
+ }else if( db->pVTab ){
const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(zFormat, pTab->zName);
rc = SQLITE_ERROR;
@@ -300,7 +327,7 @@ static int vtabCallConstructor(
rc = rc2;
}
db->pVTab = 0;
- sqliteFree(zErr);
+ sqliteFree(zModuleName);
return rc;
}
@@ -359,7 +386,7 @@ static int addToVTrans(sqlite3 *db, sqli
/* Add pVtab to the end of sqlite3.aVTrans */
db->aVTrans[db->nVTrans++] = pVtab;
- pVtab->nRef++;
+ sqlite3VtabLock(pVtab);
return SQLITE_OK;
}
@@ -444,6 +471,7 @@ int sqlite3_declare_vtab(sqlite3 *db, co
sParse.pNewTable = 0;
db->pVTab = 0;
+ assert( (rc&0xff)==rc );
return rc;
}
@@ -492,10 +520,7 @@ static void callFinaliser(sqlite3 *db, i
int (*x)(sqlite3_vtab *);
x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset);
if( x ) x(pVtab);
- pVtab->nRef--;
- if( pVtab->nRef==0 ){
- pVtab->pModule->xDisconnect(pVtab);
- }
+ sqlite3VtabUnlock(pVtab);
}
sqliteFree(db->aVTrans);
db->nVTrans = 0;
@@ -623,7 +648,11 @@ FuncDef *sqlite3VtabOverloadFunction(
void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
void *pArg;
FuncDef *pNew;
+ int rc;
+ char *zLowerName;
+ unsigned char *z;
+
/* Check to see the left operand is a column in a virtual table */
if( pExpr==0 ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef;
@@ -637,8 +666,15 @@ FuncDef *sqlite3VtabOverloadFunction(
if( pMod->xFindFunction==0 ) return pDef;
/* Call the xFuncFunction method on the virtual table implementation
- ** to see if the implementation wants to overload this function */
- if( pMod->xFindFunction(pVtab, nArg, pDef->zName, &xFunc, &pArg)==0 ){
+ ** to see if the implementation wants to overload this function
+ */
+ zLowerName = sqlite3StrDup(pDef->zName);
+ for(z=(unsigned char*)zLowerName; *z; z++){
+ *z = sqlite3UpperToLower[*z];
+ }
+ rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg);
+ sqliteFree(zLowerName);
+ if( rc==0 ){
return pDef;
}
============================================================
--- sqlite/where.c 75a89957fcb8c068bec55caa4e9d2ed5fa0b0724
+++ sqlite/where.c f55d4459a122457a135cf9ec859bf28777d9156f
@@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
-** $Id: where.c,v 1.228 2006/06/27 13:20:22 drh Exp $
+** $Id: where.c,v 1.234 2006/12/20 03:24:19 drh Exp $
*/
#include "sqliteInt.h"
@@ -157,6 +157,7 @@ struct ExprMaskSet {
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
#define WO_MATCH 64
+#define WO_ISNULL 128
/*
** Value for flags returned by bestIndex()
@@ -354,7 +355,7 @@ static int allowedOp(int op){
assert( TK_LT>TK_EQ && TK_LTTK_EQ && TK_LE=TK_EQ && op<=TK_GE);
+ return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
}
/*
@@ -388,9 +389,12 @@ static int operatorMask(int op){
assert( allowedOp(op) );
if( op==TK_IN ){
c = WO_IN;
+ }else if( op==TK_ISNULL ){
+ c = WO_ISNULL;
}else{
c = WO_EQ<<(op-TK_EQ);
}
+ assert( op!=TK_ISNULL || c==WO_ISNULL );
assert( op!=TK_IN || c==WO_IN );
assert( op!=TK_EQ || c==WO_EQ );
assert( op!=TK_LT || c==WO_LT );
@@ -422,7 +426,7 @@ static WhereTerm *findTerm(
&& pTerm->leftColumn==iColumn
&& (pTerm->eOperator & op)!=0
){
- if( iCur>=0 && pIdx ){
+ if( iCur>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
Expr *pX = pTerm->pExpr;
CollSeq *pColl;
char idxaff;
@@ -590,13 +594,17 @@ static void exprAnalyze(
Bitmask prereqAll;
int nPattern;
int isComplete;
+ int op;
if( sqlite3MallocFailed() ) return;
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
- if( pExpr->op==TK_IN ){
+ op = pExpr->op;
+ if( op==TK_IN ){
assert( pExpr->pRight==0 );
pTerm->prereqRight = exprListTableUsage(pMaskSet, pExpr->pList)
| exprSelectTableUsage(pMaskSet, pExpr->pSelect);
+ }else if( op==TK_ISNULL ){
+ pTerm->prereqRight = 0;
}else{
pTerm->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
}
@@ -608,13 +616,13 @@ static void exprAnalyze(
pTerm->leftCursor = -1;
pTerm->iParent = -1;
pTerm->eOperator = 0;
- if( allowedOp(pExpr->op) && (pTerm->prereqRight & prereqLeft)==0 ){
+ if( allowedOp(op) && (pTerm->prereqRight & prereqLeft)==0 ){
Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight;
if( pLeft->op==TK_COLUMN ){
pTerm->leftCursor = pLeft->iTable;
pTerm->leftColumn = pLeft->iColumn;
- pTerm->eOperator = operatorMask(pExpr->op);
+ pTerm->eOperator = operatorMask(op);
}
if( pRight && pRight->op==TK_COLUMN ){
WhereTerm *pNew;
@@ -622,6 +630,10 @@ static void exprAnalyze(
if( pTerm->leftCursor>=0 ){
int idxNew;
pDup = sqlite3ExprDup(pExpr);
+ if( sqlite3MallocFailed() ){
+ sqliteFree(pDup);
+ return;
+ }
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( idxNew==0 ) return;
pNew = &pWC->a[idxNew];
@@ -715,16 +727,15 @@ static void exprAnalyze(
if( ok ){
ExprList *pList = 0;
Expr *pNew, *pDup;
+ Expr *pLeft = 0;
for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;
pDup = sqlite3ExprDup(pOrTerm->pExpr->pRight);
pList = sqlite3ExprListAppend(pList, pDup, 0);
+ pLeft = pOrTerm->pExpr->pLeft;
}
- pDup = sqlite3Expr(TK_COLUMN, 0, 0, 0);
- if( pDup ){
- pDup->iTable = iCursor;
- pDup->iColumn = iColumn;
- }
+ assert( pLeft!=0 );
+ pDup = sqlite3ExprDup(pLeft);
pNew = sqlite3Expr(TK_IN, pDup, 0, 0);
if( pNew ){
int idxNew;
@@ -857,11 +868,19 @@ static int isSortingIndex(
/* Match terms of the ORDER BY clause against columns of
** the index.
+ **
+ ** Note that indices have pIdx->nColumn regular columns plus
+ ** one additional column containing the rowid. The rowid column
+ ** of the index is also allowed to match against the ORDER BY
+ ** clause.
*/
- for(i=j=0, pTerm=pOrderBy->a; jnColumn; i++){
+ for(i=j=0, pTerm=pOrderBy->a; jnColumn; i++){
Expr *pExpr; /* The expression of the ORDER BY pTerm */
CollSeq *pColl; /* The collating sequence of pExpr */
int termSortOrder; /* Sort order for this term */
+ int iColumn; /* The i-th column of the index. -1 for rowid */
+ int iSortOrder; /* 1 for DESC, 0 for ASC on the i-th index term */
+ const char *zColl; /* Name of the collating sequence for i-th index term */
pExpr = pTerm->pExpr;
if( pExpr->op!=TK_COLUMN || pExpr->iTable!=base ){
@@ -870,9 +889,22 @@ static int isSortingIndex(
return 0;
}
pColl = sqlite3ExprCollSeq(pParse, pExpr);
- if( !pColl ) pColl = db->pDfltColl;
- if( pExpr->iColumn!=pIdx->aiColumn[i] ||
- sqlite3StrICmp(pColl->zName, pIdx->azColl[i]) ){
+ if( !pColl ){
+ pColl = db->pDfltColl;
+ }
+ if( inColumn ){
+ iColumn = pIdx->aiColumn[i];
+ if( iColumn==pIdx->pTable->iPKey ){
+ iColumn = -1;
+ }
+ iSortOrder = pIdx->aSortOrder[i];
+ zColl = pIdx->azColl[i];
+ }else{
+ iColumn = -1;
+ iSortOrder = 0;
+ zColl = pColl->zName;
+ }
+ if( pExpr->iColumn!=iColumn || sqlite3StrICmp(pColl->zName, zColl) ){
/* Term j of the ORDER BY clause does not match column i of the index */
if( iaSortOrder!=0 );
assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 );
- assert( pIdx->aSortOrder[i]==0 || pIdx->aSortOrder[i]==1 );
- termSortOrder = pIdx->aSortOrder[i] ^ pTerm->sortOrder;
+ assert( iSortOrder==0 || iSortOrder==1 );
+ termSortOrder = iSortOrder ^ pTerm->sortOrder;
if( i>nEqCol ){
if( termSortOrder!=sortOrder ){
/* Indices can only be used if all ORDER BY terms past the
@@ -901,15 +933,27 @@ static int isSortingIndex(
}
j++;
pTerm++;
+ if( iColumn<0 ){
+ /* If the indexed column is the primary key and everything matches
+ ** so far, then we are assured that the index can be used to sort
+ ** because the primary key is unique and so none of the other columns
+ ** will make any difference
+ */
+ j = nTerm;
+ }
}
- /* The index can be used for sorting if all terms of the ORDER BY clause
- ** are covered.
- */
+ *pbRev = sortOrder!=0;
if( j>=nTerm ){
- *pbRev = sortOrder!=0;
+ /* All terms of the ORDER BY clause are covered by this index so
+ ** this index can be used for sorting. */
return 1;
}
+ if( j==pIdx->nColumn && pIdx->onError!=OE_None ){
+ /* All terms of this index match some prefix of the ORDER BY clause
+ ** and this index is UNIQUE, so this index can be used for sorting. */
+ return 1;
+ }
return 0;
}
@@ -928,8 +972,7 @@ static int sortableByRowid(
assert( pOrderBy!=0 );
assert( pOrderBy->nExpr>0 );
p = pOrderBy->a[0].pExpr;
- if( pOrderBy->nExpr==1 && p->op==TK_COLUMN && p->iTable==base
- && p->iColumn==-1 ){
+ if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 ){
*pbRev = pOrderBy->a[0].sortOrder;
return 1;
}
@@ -1337,7 +1380,7 @@ static double bestIndex(
flags = 0;
for(i=0; inColumn; i++){
int j = pProbe->aiColumn[i];
- pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN, pProbe);
+ pTerm = findTerm(pWC, iCur, j, notReady, WO_EQ|WO_IN|WO_ISNULL, pProbe);
if( pTerm==0 ) break;
flags |= WHERE_COLUMN_EQ;
if( pTerm->eOperator & WO_IN ){
@@ -1476,30 +1519,18 @@ static void disableTerm(WhereLevel *pLev
}
/*
-** Generate code that builds a probe for an index. Details:
+** Generate code that builds a probe for an index.
**
-** * Check the top nColumn entries on the stack. If any
-** of those entries are NULL, jump immediately to brk,
-** which is the loop exit, since no index entry will match
-** if any part of the key is NULL. Pop (nColumn+nExtra)
-** elements from the stack.
-**
-** * Construct a probe entry from the top nColumn entries in
-** the stack with affinities appropriate for index pIdx.
-** Only nColumn elements are popped from the stack in this case
-** (by OP_MakeRecord).
-**
+** There should be nColumn values on the stack. The index
+** to be probed is pIdx. Pop the values from the stack and
+** replace them all with a single record that is the index
+** problem.
*/
static void buildIndexProbe(
- Vdbe *v,
- int nColumn,
- int nExtra,
- int brk,
- Index *pIdx
+ Vdbe *v, /* Generate code into this VM */
+ int nColumn, /* The number of columns to check for NULL */
+ Index *pIdx /* Index that we will be searching */
){
- sqlite3VdbeAddOp(v, OP_NotNull, -nColumn, sqlite3VdbeCurrentAddr(v)+3);
- sqlite3VdbeAddOp(v, OP_Pop, nColumn+nExtra, 0);
- sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
sqlite3IndexAffinityStr(v, pIdx);
}
@@ -1523,15 +1554,17 @@ static void codeEqualityTerm(
WhereLevel *pLevel /* When level of the FROM clause we are working on */
){
Expr *pX = pTerm->pExpr;
- if( pX->op!=TK_IN ){
- assert( pX->op==TK_EQ );
+ Vdbe *v = pParse->pVdbe;
+ if( pX->op==TK_EQ ){
sqlite3ExprCode(pParse, pX->pRight);
+ }else if( pX->op==TK_ISNULL ){
+ sqlite3VdbeAddOp(v, OP_Null, 0, 0);
#ifndef SQLITE_OMIT_SUBQUERY
}else{
int iTab;
int *aIn;
- Vdbe *v = pParse->pVdbe;
+ assert( pX->op==TK_IN );
sqlite3CodeSubselect(pParse, pX);
iTab = pX->iTable;
sqlite3VdbeAddOp(v, OP_Rewind, iTab, 0);
@@ -1605,10 +1638,13 @@ static void codeAllEqualityTerms(
*/
for(j=0; jnColumn; j++){
int k = pIdx->aiColumn[j];
- pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN, pIdx);
+ pTerm = findTerm(pWC, iCur, k, notReady, WO_EQ|WO_IN|WO_ISNULL, pIdx);
if( pTerm==0 ) break;
assert( (pTerm->flags & TERM_CODED)==0 );
codeEqualityTerm(pParse, pTerm, brk, pLevel);
+ if( (pTerm->eOperator & WO_ISNULL)==0 ){
+ sqlite3VdbeAddOp(v, OP_IsNull, termsInMem ? -1 : -(j+1), brk);
+ }
if( termsInMem ){
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem+j+1, 1);
}
@@ -1850,8 +1886,7 @@ WhereInfo *sqlite3WhereBegin(
for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){
int doNotReorder; /* True if this table should not be reordered */
- doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0
- || (j>0 && (pTabItem[-1].jointype & (JT_LEFT|JT_CROSS))!=0);
+ doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0;
if( once && doNotReorder ) break;
m = getMask(&maskSet, pTabItem->iCursor);
if( (m & notReady)==0 ){
@@ -1986,7 +2021,9 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeOp3(v, OP_OpenRead, iIdxCur, pIx->tnum,
(char*)pKey, P3_KEYINFO_HANDOFF);
}
- if( (pLevel->flags & WHERE_IDX_ONLY)!=0 ){
+ if( (pLevel->flags & (WHERE_IDX_ONLY|WHERE_COLUMN_RANGE))!=0 ){
+ /* Only call OP_SetNumColumns on the index if we might later use
+ ** OP_Column on the index. */
sqlite3VdbeAddOp(v, OP_SetNumColumns, iIdxCur, pIx->nColumn+1);
}
sqlite3CodeVerifySchema(pParse, iDb);
@@ -2025,7 +2062,7 @@ WhereInfo *sqlite3WhereBegin(
** initialize a memory cell that records if this table matches any
** row of the left table of the join.
*/
- if( pLevel->iFrom>0 && (pTabItem[-1].jointype & JT_LEFT)!=0 ){
+ if( pLevel->iFrom>0 && (pTabItem[0].jointype & JT_LEFT)!=0 ){
if( !pParse->nMem ) pParse->nMem++;
pLevel->iLeftJoin = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_MemInt, 0, pLevel->iLeftJoin);
@@ -2159,7 +2196,6 @@ WhereInfo *sqlite3WhereBegin(
int btmEq=0; /* True if btm limit uses ==. False if strictly > */
int topOp, btmOp; /* Operators for the top and bottom search bounds */
int testOp;
- int nNotNull; /* Number of rows of index that must be non-NULL */
int topLimit = (pLevel->flags & WHERE_TOP_LIMIT)!=0;
int btmLimit = (pLevel->flags & WHERE_BTM_LIMIT)!=0;
@@ -2181,7 +2217,6 @@ WhereInfo *sqlite3WhereBegin(
** operator and the top bound is a < or <= operator. For a descending
** index the operators are reversed.
*/
- nNotNull = nEq + topLimit;
if( pIdx->aSortOrder[nEq]==SQLITE_SO_ASC ){
topOp = WO_LT|WO_LE;
btmOp = WO_GT|WO_GE;
@@ -2206,6 +2241,7 @@ WhereInfo *sqlite3WhereBegin(
pX = pTerm->pExpr;
assert( (pTerm->flags & TERM_CODED)==0 );
sqlite3ExprCode(pParse, pX->pRight);
+ sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
topEq = pTerm->eOperator & (WO_LE|WO_GE);
disableTerm(pLevel, pTerm);
testOp = OP_IdxGE;
@@ -2216,7 +2252,7 @@ WhereInfo *sqlite3WhereBegin(
if( testOp!=OP_Noop ){
int nCol = nEq + topLimit;
pLevel->iMem = pParse->nMem++;
- buildIndexProbe(v, nCol, nEq, brk, pIdx);
+ buildIndexProbe(v, nCol, pIdx);
if( bRev ){
int op = topEq ? OP_MoveLe : OP_MoveLt;
sqlite3VdbeAddOp(v, op, iIdxCur, brk);
@@ -2244,6 +2280,7 @@ WhereInfo *sqlite3WhereBegin(
pX = pTerm->pExpr;
assert( (pTerm->flags & TERM_CODED)==0 );
sqlite3ExprCode(pParse, pX->pRight);
+ sqlite3VdbeAddOp(v, OP_IsNull, -(nEq+1), brk);
btmEq = pTerm->eOperator & (WO_LE|WO_GE);
disableTerm(pLevel, pTerm);
}else{
@@ -2251,7 +2288,7 @@ WhereInfo *sqlite3WhereBegin(
}
if( nEq>0 || btmLimit ){
int nCol = nEq + btmLimit;
- buildIndexProbe(v, nCol, 0, brk, pIdx);
+ buildIndexProbe(v, nCol, pIdx);
if( bRev ){
pLevel->iMem = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
@@ -2278,8 +2315,10 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
}
}
- sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
- sqlite3VdbeAddOp(v, OP_IdxIsNull, nNotNull, cont);
+ if( topLimit | btmLimit ){
+ sqlite3VdbeAddOp(v, OP_Column, iIdxCur, nEq);
+ sqlite3VdbeAddOp(v, OP_IsNull, 1, cont);
+ }
if( !omitTable ){
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);
@@ -2305,7 +2344,7 @@ WhereInfo *sqlite3WhereBegin(
/* Generate a single key that will be used to both start and terminate
** the search
*/
- buildIndexProbe(v, nEq, 0, brk, pIdx);
+ buildIndexProbe(v, nEq, pIdx);
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
/* Generate code (1) to move to the first matching element of the table.
@@ -2326,8 +2365,6 @@ WhereInfo *sqlite3WhereBegin(
sqlite3VdbeOp3(v, OP_IdxGE, iIdxCur, brk, "+", P3_STATIC);
pLevel->op = OP_Next;
}
- sqlite3VdbeAddOp(v, OP_RowKey, iIdxCur, 0);
- sqlite3VdbeAddOp(v, OP_IdxIsNull, nEq, cont);
if( !omitTable ){
sqlite3VdbeAddOp(v, OP_IdxRowid, iIdxCur, 0);
sqlite3VdbeAddOp(v, OP_MoveGe, iCur, 0);