Index: Makefile.in
==================================================================
--- Makefile.in
+++ Makefile.in
@@ -30,10 +30,11 @@
#
CC = @CC@
CFLAGS = @CPPFLAGS@ @CFLAGS@
TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu
TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
+TCC += -I${TOP}/ext/userauth
# Define this for the autoconf-based build, so that the code knows it can
# include the generated config.h
#
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
@@ -185,11 +186,11 @@
notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
random.lo resolve.lo rowset.lo rtree.lo \
sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
- update.lo upsert.lo util.lo vacuum.lo \
+ update.lo userauth.lo upsert.lo util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
window.lo utf.lo vtab.lo
# Object files for the amalgamation.
@@ -357,10 +358,13 @@
$(TOP)/ext/sqlrr/sqlrr.c
SRC += \
$(TOP)/ext/session/sqlite3session.c \
$(TOP)/ext/session/sqlite3session.h
SRC += \
+ $(TOP)/ext/userauth/userauth.c \
+ $(TOP)/ext/userauth/sqlite3userauth.h
+SRC += \
$(TOP)/ext/rbu/sqlite3rbu.h \
$(TOP)/ext/rbu/sqlite3rbu.c
SRC += \
$(TOP)/ext/misc/json1.c \
$(TOP)/ext/misc/stmt.c
@@ -456,11 +460,12 @@
$(TOP)/ext/misc/series.c \
$(TOP)/ext/misc/spellfix.c \
$(TOP)/ext/misc/totype.c \
$(TOP)/ext/misc/unionvtab.c \
$(TOP)/ext/misc/wholenumber.c \
- $(TOP)/ext/misc/zipfile.c
+ $(TOP)/ext/misc/zipfile.c \
+ $(TOP)/ext/userauth/userauth.c
# Source code to the library files needed by the test fixture
#
TESTSRC2 = \
$(TOP)/src/attach.c \
@@ -562,10 +567,12 @@
$(TOP)/ext/rtree/geopoly.c
EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
$(TOP)/ext/rtree/sqlite3rtree.h
+EXTHDR += \
+ $(TOP)/ext/userauth/sqlite3userauth.h
EXTHDR += \
$(TOP)/ext/sqlrr/sqlrr.h
# If using the amalgamation, use sqlite3.c directly to build the test
# fixture. Otherwise link against libsqlite3.la. (This distinction is
@@ -1129,11 +1136,14 @@
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
-sqlite3session.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
+sqlite3session.lo: $(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR)
+ $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c
+
+userauth.lo: $(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c
json1.lo: $(TOP)/ext/misc/json1.c
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
Index: Makefile.msc
==================================================================
--- Makefile.msc
+++ Makefile.msc
@@ -343,10 +343,11 @@
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF
# Should the session extension be enabled? If so, add compilation options
Index: doc/lemon.html
==================================================================
--- doc/lemon.html
+++ doc/lemon.html
@@ -774,10 +774,13 @@
%include {#include <unistd.h>}
This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyped in unistd.h.
+
+Use the %code directive to add code to
+the end of the generated parser.
The %left directive
The %left directive is used (along with the
Index: ext/fts3/fts3.c
==================================================================
--- ext/fts3/fts3.c
+++ ext/fts3/fts3.c
@@ -4164,10 +4164,11 @@
}
return rc;
}
+#ifndef SQLITE_DISABLE_FTS4_DEFERRED
/*
** This function is called on each phrase after the position lists for
** any deferred tokens have been loaded into memory. It updates the phrases
** current position list to include only those positions that are really
** instances of the phrase (after considering deferred tokens). If this
@@ -4267,10 +4268,11 @@
}
}
return SQLITE_OK;
}
+#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
/*
** Maximum number of tokens a phrase may have to be considered for the
** incremental doclists strategy.
*/
Index: ext/rtree/geopoly.c
==================================================================
--- ext/rtree/geopoly.c
+++ ext/rtree/geopoly.c
@@ -542,19 +542,19 @@
}
}
#define GEOPOLY_PI 3.1415926535897932385
-/* Fast approximation for cosine(X) for X between -0.5*pi and 2*pi
+/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
*/
-static double geopolyCosine(double r){
+static double geopolySine(double r){
assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
if( r>=1.5*GEOPOLY_PI ){
r -= 2.0*GEOPOLY_PI;
}
if( r>=0.5*GEOPOLY_PI ){
- return -geopolyCosine(r-GEOPOLY_PI);
+ return -geopolySine(r-GEOPOLY_PI);
}else{
double r2 = r*r;
double r3 = r2*r;
double r5 = r3*r2;
return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
@@ -591,12 +591,12 @@
p->hdr[1] = 0;
p->hdr[2] = (n>>8)&0xff;
p->hdr[3] = n&0xff;
for(i=0; ia[i*2] = x - r*geopolyCosine(rAngle-0.5*GEOPOLY_PI);
- p->a[i*2+1] = y + r*geopolyCosine(rAngle);
+ p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
+ p->a[i*2+1] = y + r*geopolySine(rAngle);
}
sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
sqlite3_free(p);
}
Index: src/build.c
==================================================================
--- src/build.c
+++ src/build.c
@@ -542,21 +542,26 @@
** "main" and "temp") for a single database connection.
*/
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
- assert( db->nSchemaLock==0 );
for(i=0; inDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
- sqlite3SchemaClear(pDb->pSchema);
+ if( db->nSchemaLock==0 ){
+ sqlite3SchemaClear(pDb->pSchema);
+ }else{
+ DbSetProperty(db, i, DB_ResetWanted);
+ }
}
}
db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
- sqlite3CollapseDatabaseArray(db);
+ if( db->nSchemaLock==0 ){
+ sqlite3CollapseDatabaseArray(db);
+ }
}
/*
** This routine is called when a commit occurs.
*/
@@ -1892,10 +1897,11 @@
pPk->nColumn = pTab->nCol;
}
recomputeColumnsNotIndexed(pPk);
}
+#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if zName is a shadow table name in the current database
** connection.
**
** zName is temporarily modified while this routine is running, but is
@@ -1917,10 +1923,13 @@
if( pMod==0 ) return 0;
if( pMod->pModule->iVersion<3 ) return 0;
if( pMod->pModule->xShadowName==0 ) return 0;
return pMod->pModule->xShadowName(zTail+1);
}
+#else
+# define isShadowTableName(x,y) 0
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
Index: src/delete.c
==================================================================
--- src/delete.c
+++ src/delete.c
@@ -68,13 +68,15 @@
db = pParse->db;
if( (pTab->tabFlags & TF_Readonly)!=0 ){
return sqlite3WritableSchema(db)==0 && pParse->nested==0;
}
assert( pTab->tabFlags & TF_Shadow );
- return (db->flags & SQLITE_Defensive)!=0
- && db->nVdbeExec==0
- && db->pVtabCtx==0;
+ return (db->flags & SQLITE_Defensive)!=0
+#ifndef SQLITE_OMIT_VIRTUALTABLE
+ && db->pVtabCtx==0
+#endif
+ && db->nVdbeExec==0;
}
/*
** Check to make sure the given table is writable. If it is not
** writable, generate an error message and return 1. If it is
Index: src/loadext.c
==================================================================
--- src/loadext.c
+++ src/loadext.c
@@ -82,10 +82,11 @@
# define sqlite3_create_module 0
# define sqlite3_create_module_v2 0
# define sqlite3_declare_vtab 0
# define sqlite3_vtab_config 0
# define sqlite3_vtab_on_conflict 0
+# define sqlite3_vtab_collation 0
#endif
#ifdef SQLITE_OMIT_SHARED_CACHE
# define sqlite3_enable_shared_cache 0
#endif
Index: src/pager.c
==================================================================
--- src/pager.c
+++ src/pager.c
@@ -847,23 +847,10 @@
#endif
return 1;
}
#endif
-/*
-** Return true if this pager uses a write-ahead log to read page pgno.
-** Return false if the pager reads pgno directly from the database.
-*/
-#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
-int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
- u32 iRead = 0;
- int rc;
- if( pPager->pWal==0 ) return 0;
- rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
- return rc || iRead;
-}
-#endif
#ifndef SQLITE_OMIT_WAL
# define pagerUseWal(x) ((x)->pWal!=0)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
@@ -7078,12 +7065,15 @@
void *(*xCodec)(void*,void*,Pgno,int),
void (*xCodecSizeChng)(void*,int,int),
void (*xCodecFree)(void*),
void *pCodec
){
- pager_reset(pPager);
- if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
+ if( pPager->xCodecFree ){
+ pPager->xCodecFree(pPager->pCodec);
+ }else{
+ pager_reset(pPager);
+ }
pPager->xCodec = pPager->memDb ? 0 : xCodec;
pPager->xCodecSizeChng = xCodecSizeChng;
pPager->xCodecFree = xCodecFree;
pPager->pCodec = pCodec;
setGetterMethod(pPager);
Index: src/pager.h
==================================================================
--- src/pager.h
+++ src/pager.h
@@ -177,22 +177,17 @@
int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
int sqlite3PagerWalSupported(Pager *pPager);
int sqlite3PagerWalCallback(Pager *pPager);
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
-# ifdef SQLITE_DIRECT_OVERFLOW_READ
- int sqlite3PagerUseWal(Pager *pPager, Pgno);
-# endif
# ifdef SQLITE_ENABLE_SNAPSHOT
int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
int sqlite3PagerSnapshotRecover(Pager *pPager);
int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
-#else
-# define sqlite3PagerUseWal(x,y) 0
#endif
#ifdef SQLITE_DIRECT_OVERFLOW_READ
int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif
Index: src/pcache1.c
==================================================================
--- src/pcache1.c
+++ src/pcache1.c
@@ -103,11 +103,12 @@
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
PgHdr1 *pLruPrev; /* Previous in LRU list of unpinned pages */
};
/*
-** A page is pinned if it is no on the LRU list
+** A page is pinned if it is not on the LRU list. To be "pinned" means
+** that the page is in active use and must not be deallocated.
*/
#define PAGE_IS_PINNED(p) ((p)->pLruNext==0)
#define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0)
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
Index: src/sqlite.h.in
==================================================================
--- src/sqlite.h.in
+++ src/sqlite.h.in
@@ -3632,11 +3632,11 @@
**
** [[SQLITE_PREPARE_NORMALIZE]] ^(SQLITE_PREPARE_NORMALIZE
** The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
** representation of the SQL statement should be calculated and then
** associated with the prepared statement, which can be obtained via
-** the [sqlite3_normalized_sql()] interface. The semantics used to
+** the [sqlite3_normalized_sql()] interface.)^ The semantics used to
** normalize a SQL statement are unspecified and subject to change.
** At a minimum, literal values will be replaced with suitable
** placeholders.
**
*/
Index: test/attach.test
==================================================================
--- test/attach.test
+++ test/attach.test
@@ -724,11 +724,11 @@
DELETE FROM t1 WHERE x<(SELECT min(x) FROM temp.t6);
END;
} db2
} {1 {trigger r5 cannot reference objects in database temp}}
} ;# endif subquery
-ifcapable json1 {
+ifcapable json1&&vtab {
do_test attach-5.10 {
db close
catch {db2 close}
forcedelete test.db
sqlite3 db test.db
Index: test/incrvacuum.test
==================================================================
--- test/incrvacuum.test
+++ test/incrvacuum.test
@@ -786,49 +786,51 @@
#-------------------------------------------------------------------------
# At one point it was unsafe to truncate a db file on windows while there
# were outstanding xFetch() references. This test case attempts to hit
# that case.
#
-reset_db
-do_execsql_test incrvacuum-16.0 {
- PRAGMA auto_vacuum = 2;
- CREATE TABLE t3(a);
- INSERT INTO t3 VALUES(1), (2), (3), (4);
-
- CREATE TABLE t2(x);
- INSERT INTO t2 VALUES( randomblob(1000) );
- INSERT INTO t2 VALUES( randomblob(1000) );
- INSERT INTO t2 VALUES( randomblob(1000) );
- INSERT INTO t2 VALUES( randomblob(1000) );
- INSERT INTO t2 VALUES( randomblob(1000) );
- INSERT INTO t2 VALUES( randomblob(1000) );
-} {}
-
-# Reopen db to ensure the page-cache is empty.
-#
-db close
-sqlite3 db test.db
-
-# Open db in mmap-mode. Open a transaction, delete some data, then run
-# incremental-vacuum. Do not commit the transaction.
-#
-do_execsql_test incrvacuum-16.1 {
- PRAGMA mmap_size = 1000000;
- BEGIN;
- DELETE FROM t2;
- PRAGMA incremental_vacuum = 1000;
-} {1000000}
-
-# Scan through table t3 (which is all clean pages - so mmap is used). Then,
-# midway through, commit the transaction. This causes the db to be truncated
-# while there are outstanding xFetch pages.
-#
-do_test incrvacuum-16.2 {
- set res [list]
- db eval { SELECT a FROM t3 } {
- if {$a==3} { db eval COMMIT }
- lappend res $a
- }
- set res
-} {1 2 3 4}
-
+ifcapable mmap {
+ reset_db
+ do_execsql_test incrvacuum-16.0 {
+ PRAGMA auto_vacuum = 2;
+ CREATE TABLE t3(a);
+ INSERT INTO t3 VALUES(1), (2), (3), (4);
+
+ CREATE TABLE t2(x);
+ INSERT INTO t2 VALUES( randomblob(1000) );
+ INSERT INTO t2 VALUES( randomblob(1000) );
+ INSERT INTO t2 VALUES( randomblob(1000) );
+ INSERT INTO t2 VALUES( randomblob(1000) );
+ INSERT INTO t2 VALUES( randomblob(1000) );
+ INSERT INTO t2 VALUES( randomblob(1000) );
+ } {}
+
+ # Reopen db to ensure the page-cache is empty.
+ #
+ db close
+ sqlite3 db test.db
+
+ # Open db in mmap-mode. Open a transaction, delete some data, then run
+ # incremental-vacuum. Do not commit the transaction.
+ #
+ do_execsql_test incrvacuum-16.1 {
+ PRAGMA mmap_size = 1000000;
+ BEGIN;
+ DELETE FROM t2;
+ PRAGMA incremental_vacuum = 1000;
+ } {1000000}
+
+ # Scan through table t3 (which is all clean pages - so mmap is used). Then,
+ # midway through, commit the transaction. This causes the db to be truncated
+ # while there are outstanding xFetch pages.
+ #
+ do_test incrvacuum-16.2 {
+ set res [list]
+ db eval { SELECT a FROM t3 } {
+ if {$a==3} { db eval COMMIT }
+ lappend res $a
+ }
+ set res
+ } {1 2 3 4}
+}
+
finish_test
Index: test/indexexpr2.test
==================================================================
--- test/indexexpr2.test
+++ test/indexexpr2.test
@@ -199,35 +199,37 @@
} {0}
# Additional test cases to show that UPDATE does not modify indexes that
# do not involve unchanged columns.
#
-load_static_extension db explain
-do_execsql_test 4.200 {
- CREATE TABLE t2(a,b,c,d,e,f);
- INSERT INTO t2 VALUES(2,3,4,5,6,7);
- CREATE INDEX t2abc ON t2(a+b+c);
- CREATE INDEX t2cd ON t2(c*d);
- CREATE INDEX t2def ON t2(d,e+25*f);
- SELECT sqlite_master.name
- FROM sqlite_master, explain('UPDATE t2 SET b=b+1')
- WHERE explain.opcode LIKE 'Open%'
- AND sqlite_master.rootpage=explain.p2
- ORDER BY 1;
-} {t2 t2abc}
-do_execsql_test 4.210 {
- SELECT sqlite_master.name
- FROM sqlite_master, explain('UPDATE t2 SET c=c+1')
- WHERE explain.opcode LIKE 'Open%'
- AND sqlite_master.rootpage=explain.p2
- ORDER BY 1;
-} {t2 t2abc t2cd}
-do_execsql_test 4.220 {
- SELECT sqlite_master.name
- FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
- WHERE explain.opcode LIKE 'Open%'
- AND sqlite_master.rootpage=explain.p2
- ORDER BY 1;
-} {t2 t2abc t2cd t2def}
+ifcapable vtab {
+ load_static_extension db explain
+ do_execsql_test 4.200 {
+ CREATE TABLE t2(a,b,c,d,e,f);
+ INSERT INTO t2 VALUES(2,3,4,5,6,7);
+ CREATE INDEX t2abc ON t2(a+b+c);
+ CREATE INDEX t2cd ON t2(c*d);
+ CREATE INDEX t2def ON t2(d,e+25*f);
+ SELECT sqlite_master.name
+ FROM sqlite_master, explain('UPDATE t2 SET b=b+1')
+ WHERE explain.opcode LIKE 'Open%'
+ AND sqlite_master.rootpage=explain.p2
+ ORDER BY 1;
+ } {t2 t2abc}
+ do_execsql_test 4.210 {
+ SELECT sqlite_master.name
+ FROM sqlite_master, explain('UPDATE t2 SET c=c+1')
+ WHERE explain.opcode LIKE 'Open%'
+ AND sqlite_master.rootpage=explain.p2
+ ORDER BY 1;
+ } {t2 t2abc t2cd}
+ do_execsql_test 4.220 {
+ SELECT sqlite_master.name
+ FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
+ WHERE explain.opcode LIKE 'Open%'
+ AND sqlite_master.rootpage=explain.p2
+ ORDER BY 1;
+ } {t2 t2abc t2cd t2def}
+}
finish_test
ADDED test/lemon-test01.y
Index: test/lemon-test01.y
==================================================================
--- /dev/null
+++ test/lemon-test01.y
@@ -0,0 +1,75 @@
+// A test case for the LEMON parser generator. Run as follows:
+//
+// lemon lemon-test01.y && gcc -g lemon-test01.c && ./a.out
+//
+%token_prefix TK_
+%token_type int
+%default_type int
+%include {
+ static int nSyntaxError = 0;
+ static int nAccept = 0;
+ static int nFailure = 0;
+}
+
+all ::= A B.
+all ::= error B.
+
+%syntax_error {
+ nSyntaxError++;
+}
+%parse_accept {
+ nAccept++;
+}
+%parse_failure {
+ nFailure++;
+}
+%code {
+ #include
+ #include "lemon-test01.h"
+ static int nTest = 0;
+ static int nErr = 0;
+ static int testCase(int testId, int shouldBe, int actual){
+ nTest++;
+ if( shouldBe==actual ){
+ printf("test %d: ok\n", testId);
+ }else{
+ printf("test %d: got %d, expected %d\n", testId, actual, shouldBe);
+ nErr++;
+ }
+ }
+ int main(int argc, char **argv){
+ yyParser xp;
+ ParseInit(&xp);
+ Parse(&xp, TK_A, 0);
+ Parse(&xp, TK_B, 0);
+ Parse(&xp, 0, 0);
+ ParseFinalize(&xp);
+ testCase(100, 0, nSyntaxError);
+ testCase(110, 1, nAccept);
+ testCase(120, 0, nFailure);
+ nSyntaxError = nAccept = nFailure = 0;
+ ParseInit(&xp);
+ Parse(&xp, TK_B, 0);
+ Parse(&xp, TK_B, 0);
+ Parse(&xp, 0, 0);
+ ParseFinalize(&xp);
+ testCase(200, 1, nSyntaxError);
+ testCase(210, 1, nAccept);
+ testCase(220, 0, nFailure);
+ nSyntaxError = nAccept = nFailure = 0;
+ ParseInit(&xp);
+ Parse(&xp, TK_A, 0);
+ Parse(&xp, TK_A, 0);
+ Parse(&xp, 0, 0);
+ ParseFinalize(&xp);
+ testCase(200, 1, nSyntaxError);
+ testCase(210, 0, nAccept);
+ testCase(220, 0, nFailure);
+ if( nErr==0 ){
+ printf("%d tests pass\n", nTest);
+ }else{
+ printf("%d errors out %d tests\n", nErr, nTest);
+ }
+ return nErr;
+ }
+}
Index: test/pragma4.test
==================================================================
--- test/pragma4.test
+++ test/pragma4.test
@@ -122,12 +122,12 @@
sqlite3 db3 test.db
sqlite3 db2 test.db2
execsql { DROP TABLE t1 } db3
execsql { DROP TABLE t2 } db2
} {}
-do_execsql_test 4.1.5 { PRAGMA table_info = t1 }
-do_execsql_test 4.1.6 { PRAGMA table_info = t2 }
+do_execsql_test 4.1.5 { PRAGMA table_info(t1) }
+do_execsql_test 4.1.6 { PRAGMA table_info(t2) }
db2 close
db3 close
reset_db
forcedelete test.db2
@@ -134,24 +134,28 @@
do_execsql_test 4.2.1 {
CREATE TABLE t1(a, b, c);
ATTACH 'test.db2' AS aux;
CREATE TABLE aux.t2(d, e, f);
}
-do_execsql_test 4.2.2 { SELECT * FROM pragma_table_info('t1') } {
- 0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0
-}
-do_execsql_test 4.2.3 { SELECT * FROM pragma_table_info('t2') } {
- 0 d {} 0 {} 0 1 e {} 0 {} 0 2 f {} 0 {} 0
+ifcapable vtab {
+ do_execsql_test 4.2.2 { SELECT * FROM pragma_table_info('t1') } {
+ 0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0
+ }
+ do_execsql_test 4.2.3 { SELECT * FROM pragma_table_info('t2') } {
+ 0 d {} 0 {} 0 1 e {} 0 {} 0 2 f {} 0 {} 0
+ }
}
do_test 4.2.4 {
sqlite3 db3 test.db
sqlite3 db2 test.db2
execsql { DROP TABLE t1 } db3
execsql { DROP TABLE t2 } db2
} {}
-do_execsql_test 4.2.5 { SELECT * FROM pragma_table_info('t1') }
-do_execsql_test 4.2.6 { SELECT * FROM pragma_table_info('t2') }
+ifcapable vtab {
+ do_execsql_test 4.2.5 { SELECT * FROM pragma_table_info('t1') }
+ do_execsql_test 4.2.6 { SELECT * FROM pragma_table_info('t2') }
+}
db2 close
db3 close
reset_db
forcedelete test.db2
@@ -160,52 +164,67 @@
CREATE INDEX i1 ON t1(b);
ATTACH 'test.db2' AS aux;
CREATE TABLE aux.t2(d, e, f);
CREATE INDEX aux.i2 ON t2(e);
}
-do_execsql_test 4.3.2 { SELECT * FROM pragma_index_info('i1') } {0 1 b}
-do_execsql_test 4.3.3 { SELECT * FROM pragma_index_info('i2') } {0 1 e}
+ifcapable vtab {
+ do_execsql_test 4.3.2 { SELECT * FROM pragma_index_info('i1') } {0 1 b}
+ do_execsql_test 4.3.3 { SELECT * FROM pragma_index_info('i2') } {0 1 e}
+}
do_test 4.3.4 {
sqlite3 db3 test.db
sqlite3 db2 test.db2
execsql { DROP INDEX i1 } db3
execsql { DROP INDEX i2 } db2
} {}
-do_execsql_test 4.3.5 { SELECT * FROM pragma_index_info('i1') }
-do_execsql_test 4.3.6 { SELECT * FROM pragma_index_info('i2') }
+ifcapable vtab {
+ do_execsql_test 4.3.5 { SELECT * FROM pragma_index_info('i1') }
+ do_execsql_test 4.3.6 { SELECT * FROM pragma_index_info('i2') }
+}
+execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
do_execsql_test 4.4.0 {
CREATE INDEX main.i1 ON t1(b, c);
CREATE INDEX aux.i2 ON t2(e, f);
}
-do_execsql_test 4.4.1 { SELECT * FROM pragma_index_list('t1') } {0 i1 0 c 0}
-do_execsql_test 4.4.2 { SELECT * FROM pragma_index_list('t2') } {0 i2 0 c 0}
+ifcapable vtab {
+ do_execsql_test 4.4.1 { SELECT * FROM pragma_index_list('t1') } {0 i1 0 c 0}
+ do_execsql_test 4.4.2 { SELECT * FROM pragma_index_list('t2') } {0 i2 0 c 0}
+}
do_test 4.4.3 {
execsql { DROP INDEX i1 } db3
execsql { DROP INDEX i2 } db2
} {}
-do_execsql_test 4.4.5 { SELECT * FROM pragma_index_list('t1') } {}
-do_execsql_test 4.4.6 { SELECT * FROM pragma_index_list('t2') } {}
+ifcapable vtab {
+ do_execsql_test 4.4.5 { SELECT * FROM pragma_index_list('t1') } {}
+ do_execsql_test 4.4.6 { SELECT * FROM pragma_index_list('t2') } {}
+}
+execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
do_execsql_test 4.5.0 {
CREATE UNIQUE INDEX main.i1 ON t1(a);
CREATE UNIQUE INDEX aux.i2 ON t2(d);
CREATE TABLE main.c1 (a, b, c REFERENCES t1(a));
CREATE TABLE aux.c2 (d, e, r REFERENCES t2(d));
}
-do_execsql_test 4.5.1 { SELECT * FROM pragma_foreign_key_list('c1') } {
- 0 0 t1 c a {NO ACTION} {NO ACTION} NONE
-}
-do_execsql_test 4.5.2 { SELECT * FROM pragma_foreign_key_list('c2') } {
- 0 0 t2 r d {NO ACTION} {NO ACTION} NONE
+ifcapable vtab {
+ do_execsql_test 4.5.1 { SELECT * FROM pragma_foreign_key_list('c1') } {
+ 0 0 t1 c a {NO ACTION} {NO ACTION} NONE
+ }
+ do_execsql_test 4.5.2 { SELECT * FROM pragma_foreign_key_list('c2') } {
+ 0 0 t2 r d {NO ACTION} {NO ACTION} NONE
+ }
}
do_test 4.5.3 {
execsql { DROP TABLE c1 } db3
execsql { DROP TABLE c2 } db2
} {}
-do_execsql_test 4.5.1 { SELECT * FROM pragma_foreign_key_list('c1') }
-do_execsql_test 4.5.2 { SELECT * FROM pragma_foreign_key_list('c2') }
+ifcapable vtab {
+ do_execsql_test 4.5.4 { SELECT * FROM pragma_foreign_key_list('c1') }
+ do_execsql_test 4.5.5 { SELECT * FROM pragma_foreign_key_list('c2') }
+}
+execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
do_execsql_test 4.6.0 {
CREATE TABLE main.c1 (a, b, c REFERENCES t1(a));
CREATE TABLE aux.c2 (d, e, r REFERENCES t2(d));
INSERT INTO main.c1 VALUES(1, 2, 3);
@@ -224,6 +243,5 @@
do_catchsql_test 4.6.5 {
pragma foreign_key_check('c2')
} {1 {no such table: c2}}
finish_test
-
Index: test/releasetest.tcl
==================================================================
--- test/releasetest.tcl
+++ test/releasetest.tcl
@@ -77,10 +77,13 @@
"Unlock-Notify" {
-O2
-DSQLITE_ENABLE_UNLOCK_NOTIFY
-DSQLITE_THREADSAFE
-DSQLITE_TCL_DEFAULT_FULLMUTEX=1
+ }
+ "User-Auth" {
+ -O2
-DSQLITE_USER_AUTHENTICATION=1
}
"Secure-Delete" {
-O2
-DSQLITE_SECURE_DELETE=1
@@ -272,10 +275,11 @@
"Fast-One" "fuzztest test"
"Debug-One" "mptest test"
"Have-Not" test
"Secure-Delete" test
"Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test"
+ "User-Auth" tcltest
"Update-Delete-Limit" test
"Extra-Robustness" test
"Device-Two" test
"No-lookaside" test
"Devkit" test
Index: test/vtab_err.test
==================================================================
--- test/vtab_err.test
+++ test/vtab_err.test
@@ -18,11 +18,10 @@
finish_test
return
}
-
unset -nocomplain echo_module_begin_fail
do_ioerr_test vtab_err-1 -tclprep {
register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
BEGIN;
@@ -60,7 +59,29 @@
INSERT INTO e SELECT a||'x', b, c FROM r2;
COMMIT;
}
sqlite3_memdebug_fail -1
+
+reset_db
+register_echo_module [sqlite3_connection_pointer db]
+do_execsql_test vtab_err-3.0 {
+ CREATE TABLE r(a PRIMARY KEY, b, c);
+ CREATE VIRTUAL TABLE e USING echo(r);
+}
+faultsim_save_and_close
+
+do_faultsim_test vtab_err-3 -faults oom-t* -prep {
+ faultsim_restore_and_reopen
+ register_echo_module [sqlite3_connection_pointer db]
+} -body {
+ execsql {
+ BEGIN;
+ CREATE TABLE xyz(x);
+ SELECT a FROM e;
+ COMMIT;
+ }
+} -test {
+ faultsim_test_result {0 {}}
+}
finish_test
Index: tool/lempar.c
==================================================================
--- tool/lempar.c
+++ tool/lempar.c
@@ -21,10 +21,11 @@
**
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
#include
+#include
/************ Begin %include sections from the grammar ************************/
%%
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders". This section is blank unless
@@ -985,14 +986,13 @@
#endif
yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
yymajor = YYNOCODE;
}else{
while( yypParser->yytos >= yypParser->yystack
- && yymx != YYERRORSYMBOL
&& (yyact = yy_find_reduce_action(
yypParser->yytos->stateno,
- YYERRORSYMBOL)) >= YY_MIN_REDUCE
+ YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
){
yy_pop_parser_stack(yypParser);
}
if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);