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.
@@ -354,10 +355,13 @@
$(TOP)/ext/rtree/geopoly.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
@@ -453,11 +457,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 \
@@ -469,10 +474,11 @@
$(TOP)/src/date.c \
$(TOP)/src/dbpage.c \
$(TOP)/src/dbstat.c \
$(TOP)/src/expr.c \
$(TOP)/src/func.c \
+ $(TOP)/src/global.c \
$(TOP)/src/insert.c \
$(TOP)/src/wal.c \
$(TOP)/src/main.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
@@ -558,10 +564,12 @@
$(TOP)/ext/rtree/geopoly.c
EXTHDR += \
$(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
$(TOP)/ext/rtree/sqlite3rtree.h
+EXTHDR += \
+ $(TOP)/ext/userauth/sqlite3userauth.h
# executables needed for testing
#
TESTPROGS = \
testfixture$(TEXE) \
@@ -1115,11 +1123,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: ext/rtree/sqlite3rtree.h
==================================================================
--- ext/rtree/sqlite3rtree.h
+++ ext/rtree/sqlite3rtree.h
@@ -94,11 +94,11 @@
int iLevel; /* Level of current node or entry */
int mxLevel; /* The largest iLevel value in the tree */
sqlite3_int64 iRowid; /* Rowid for current entry */
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
int eParentWithin; /* Visibility of parent node */
- int eWithin; /* OUT: Visiblity */
+ int eWithin; /* OUT: Visibility */
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
/* The following fields are only available in 3.8.11 and later */
sqlite3_value **apSqlParam; /* Original SQL values of parameters */
};
Index: main.mk
==================================================================
--- main.mk
+++ main.mk
@@ -394,10 +394,11 @@
$(TOP)/src/date.c \
$(TOP)/src/dbpage.c \
$(TOP)/src/dbstat.c \
$(TOP)/src/expr.c \
$(TOP)/src/func.c \
+ $(TOP)/src/global.c \
$(TOP)/src/insert.c \
$(TOP)/src/wal.c \
$(TOP)/src/main.c \
$(TOP)/src/mem5.c \
$(TOP)/src/os.c \
Index: src/alter.c
==================================================================
--- src/alter.c
+++ src/alter.c
@@ -665,14 +665,20 @@
#else
# define renameTokenCheckAll(x,y)
#endif
/*
-** Add a new RenameToken object mapping parse tree element pPtr into
-** token *pToken to the Parse object currently under construction.
+** Remember that the parser tree element pPtr was created using
+** the token pToken.
+**
+** In other words, construct a new RenameToken object and add it
+** to the list of RenameToken objects currently being built up
+** in pParse->pRename.
**
-** Return a copy of pPtr.
+** The pPtr argument is returned so that this routine can be used
+** with tail recursion in tokenExpr() routine, for a small performance
+** improvement.
*/
void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){
RenameToken *pNew;
assert( pPtr || pParse->db->mallocFailed );
renameTokenCheckAll(pParse, pPtr);
@@ -1180,19 +1186,12 @@
** Do a column rename operation on the CREATE statement given in zSql.
** The iCol-th column (left-most is 0) of table zTable is renamed from zCol
** into zNew. The name should be quoted if bQuote is true.
**
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
-** Though accessible to application code, it is not intended for use by
-** applications. The existance of this function, and the way it works,
-** is subject to change without notice.
-**
-** If any of the parameters are out-of-bounds, then simply return NULL.
-** An out-of-bounds parameter can only occur when the application calls
-** this function directly. The parameters will always be well-formed when
-** this routine is invoked by the bytecode for a legitimate ALTER TABLE
-** statement.
+** It is only accessible to SQL created using sqlite3NestedParse(). It is
+** not reachable from ordinary SQL passed into sqlite3_prepare().
*/
static void renameColumnFunc(
sqlite3_context *context,
int NotUsed,
sqlite3_value **argv
@@ -1596,12 +1595,12 @@
/*
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
static FuncDef aAlterTableFuncs[] = {
- FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc),
- FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc),
- FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest),
+ INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
+ INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
+ INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest),
};
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif /* SQLITE_ALTER_TABLE */
Index: src/build.c
==================================================================
--- src/build.c
+++ src/build.c
@@ -544,21 +544,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.
*/
@@ -1894,10 +1899,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
@@ -1919,10 +1925,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/global.c
==================================================================
--- src/global.c
+++ src/global.c
@@ -238,10 +238,11 @@
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
0, /* bLocaltimeFault */
+ 0, /* bInternalFunctions */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE /* szSorterRef */
};
/*
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/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -3951,18 +3951,29 @@
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff);
**
- ** If parameter onoff is non-zero, configure the wrappers so that all
- ** subsequent calls to localtime() and variants fail. If onoff is zero,
- ** undo this setting.
+ ** If parameter onoff is non-zero, subsequent calls to localtime()
+ ** and its variants fail. If onoff is zero, undo this setting.
*/
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
break;
}
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCS, int onoff);
+ **
+ ** If parameter onoff is non-zero, internal-use-only SQL functions
+ ** are visible to ordinary SQL. This is useful for testing but is
+ ** unsafe because invalid parameters to those internal-use-only functions
+ ** can result in crashes or segfaults.
+ */
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: {
+ sqlite3GlobalConfig.bInternalFunctions = va_arg(ap, int);
+ break;
+ }
/* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
**
** Set or clear a flag that indicates that the database file is always well-
** formed and never corrupt. This flag is clear by default, indicating that
Index: src/pager.c
==================================================================
--- src/pager.c
+++ src/pager.c
@@ -850,23 +850,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
@@ -7198,12 +7185,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
@@ -178,22 +178,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/pragma.c
==================================================================
--- src/pragma.c
+++ src/pragma.c
@@ -1237,10 +1237,11 @@
HashElem *j;
FuncDef *p;
pParse->nMem = 2;
for(i=0; iu.pHash ){
+ if( p->funcFlags & SQLITE_FUNC_INTERNAL ) continue;
sqlite3VdbeMultiLoad(v, 1, "si", p->zName, 1);
}
}
for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
p = (FuncDef*)sqliteHashData(j);
Index: src/resolve.c
==================================================================
--- src/resolve.c
+++ src/resolve.c
@@ -768,10 +768,19 @@
/* Date/time functions that use 'now', and other functions like
** sqlite_version() that might change over time cannot be used
** in an index. */
notValid(pParse, pNC, "non-deterministic functions",
NC_IdxExpr|NC_PartIdx);
+ }
+ if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
+ && pParse->nested==0
+ && sqlite3Config.bInternalFunctions==0
+ ){
+ /* Internal-use-only functions are disallowed unless the
+ ** SQL is being compiled using sqlite3NestedParse() */
+ no_such_func = 1;
+ pDef = 0;
}
}
if( 0==IN_RENAME_OBJECT ){
#ifndef SQLITE_OMIT_WINDOWFUNC
Index: src/shell.c.in
==================================================================
--- src/shell.c.in
+++ src/shell.c.in
@@ -7675,10 +7675,11 @@
/*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
/*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
+ { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
{ "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
#ifdef YYCOVERAGE
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
@@ -7769,10 +7770,11 @@
break;
/* sqlite3_test_control(int, int) */
case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS:
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
if( nArg==3 ){
int opt = booleanValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, opt);
isOk = 1;
}
Index: src/sqlite.h.in
==================================================================
--- src/sqlite.h.in
+++ src/sqlite.h.in
@@ -3631,11 +3631,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.
**
*/
@@ -7240,10 +7240,11 @@
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
+#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
Index: src/sqliteInt.h
==================================================================
--- src/sqliteInt.h
+++ src/sqliteInt.h
@@ -1693,12 +1693,13 @@
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
#define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */
-#define SQLITE_FUNC_WINDOW 0x10000 /* Built-in window-only function */
-#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
+#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
+#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
+#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
/*
** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
** used to create the initializers for the FuncDef structures.
**
@@ -1770,14 +1771,17 @@
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,0,#zName, {0}}
#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xFinal,0,#zName, {0}}
-
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
+#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
+ {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
+ 0, 0, xFunc, 0, 0, 0, #zName, {0} }
+
/*
** All current savepoints are stored in a linked list starting at
** sqlite3.pSavepoint. The first element in the list is the most recently
** opened savepoint. Savepoints are added to the list by the vdbe
@@ -3424,10 +3428,11 @@
#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
int bLocaltimeFault; /* True to fail localtime() calls */
+ int bInternalFunctions; /* Internal SQL functions are visible */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
};
/*
Index: src/test1.c
==================================================================
--- src/test1.c
+++ src/test1.c
@@ -6327,11 +6327,11 @@
}
/*
** tclcmd: database_may_be_corrupt
**
-** Indicate that database files might be corrupt. In other words, set the normal
+** Indicate that database files might be corrupt. In other words, set the normal
** state of operation.
*/
static int SQLITE_TCLAPI database_may_be_corrupt(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
@@ -6342,12 +6342,13 @@
return TCL_OK;
}
/*
** tclcmd: database_never_corrupt
**
-** Indicate that database files are always well-formed. This enables extra assert()
-** statements that test conditions that are always true for well-formed databases.
+** Indicate that database files are always well-formed. This enables
+** extra assert() statements that test conditions that are always true
+** for well-formed databases.
*/
static int SQLITE_TCLAPI database_never_corrupt(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
@@ -6709,13 +6710,14 @@
){
struct Verb {
const char *zName;
int i;
} aVerb[] = {
- { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
- { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
- { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER },
+ { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
+ { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP },
+ { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER },
+ { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS},
};
int iVerb;
int iFlag;
int rc;
@@ -6729,18 +6731,19 @@
);
if( rc!=TCL_OK ) return rc;
iFlag = aVerb[iVerb].i;
switch( iFlag ){
+ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
int val;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
return TCL_ERROR;
}
if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
- sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
+ sqlite3_test_control(iFlag, val);
break;
}
case SQLITE_TESTCTRL_SORTER_MMAP: {
int val;
Index: test/alter.test
==================================================================
--- test/alter.test
+++ test/alter.test
@@ -682,10 +682,11 @@
#--------------------------------------------------------------------------
# alter-9.X - Special test: Make sure the sqlite_rename_column() and
# rename_table() functions do not crash when handed bad input.
#
+sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test alter-9.1 {
execsql {SELECT SQLITE_RENAME_COLUMN(0,0,0,0,0,0,0,0,0)}
} {{}}
foreach {tn sql} {
1 { SELECT SQLITE_RENAME_TABLE(0,0,0,0,0,0,0) }
@@ -694,10 +695,18 @@
} {
do_test alter-9.2.$tn {
catch { execsql $sql }
} 1
}
+sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
+
+# If the INTERNAL_FUNCTIONS test-control is disabled (which is the default),
+# then the sqlite_rename_table() SQL function is not accessible to ordinary SQL.
+#
+do_catchsql_test alter-9.3 {
+ SELECT sqlite_rename_table(0,0,0,0,0,0,0);
+} {1 {no such function: sqlite_rename_table}}
#------------------------------------------------------------------------
# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters
# in the names.
#
Index: test/altercol.test
==================================================================
--- test/altercol.test
+++ test/altercol.test
@@ -616,10 +616,11 @@
}
#-------------------------------------------------------------------------
# Passing invalid parameters directly to sqlite_rename_column().
#
+sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_execsql_test 14.1 {
CREATE TABLE ddd(sql, type, object, db, tbl, icol, znew, bquote);
INSERT INTO ddd VALUES(
'CREATE TABLE x1(i INTEGER, t TEXT)',
'table', 'x1', 'main', 'x1', -1, 'zzz', 0
@@ -638,10 +639,19 @@
do_execsql_test 14.2 {
SELECT
sqlite_rename_column(sql, type, object, db, tbl, icol, znew, bquote, 0)
FROM ddd;
} {{} {} {} {}}
+sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
+
+# If the INTERNAL_FUNCTIONS test-control is disabled (which is the default)
+# then the sqlite_rename_table() SQL function is not accessible to
+# ordinary SQL.
+#
+do_catchsql_test 14.3 {
+ SELECT sqlite_rename_column(0,0,0,0,0,0,0,0,0);
+} {1 {no such function: sqlite_rename_column}}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 15.0 {
Index: test/altertab.test
==================================================================
--- test/altertab.test
+++ test/altertab.test
@@ -238,15 +238,17 @@
), (
'main', NULL, 'ddd', 'eee', 0
);
} {}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_execsql_test 7.2 {
SELECT
sqlite_rename_table(db, 0, 0, sql, zOld, zNew, bTemp)
FROM ddd;
} {{} {} {}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
}
#-------------------------------------------------------------------------
#
reset_db
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/fkey2.test
==================================================================
--- test/fkey2.test
+++ test/fkey2.test
@@ -985,19 +985,21 @@
proc test_rename_parent {zCreate zOld zNew} {
db eval {SELECT sqlite_rename_table(
'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
)}
}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test fkey2-14.2.1.1 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
do_test fkey2-14.2.1.2 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
} {{CREATE TABLE t1(a REFERENCES t2)}}
do_test fkey2-14.2.1.3 {
test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
# Test ALTER TABLE RENAME TABLE a bit.
#
do_test fkey2-14.2.2.1 {
drop_all_tables
@@ -1066,19 +1068,21 @@
PRAGMA foreign_keys = on;
SELECT sql FROM temp.sqlite_master WHERE name='t2';
}
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test fkey2-14.2tmp.1.1 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
do_test fkey2-14.2tmp.1.2 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
} {{CREATE TABLE t1(a REFERENCES t2)}}
do_test fkey2-14.2tmp.1.3 {
test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
# Test ALTER TABLE RENAME TABLE a bit.
#
do_test fkey2-14.2tmp.2.1 {
drop_all_tables
@@ -1148,19 +1152,21 @@
PRAGMA foreign_keys = on;
SELECT sql FROM aux.sqlite_master WHERE name='t2';
}
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test fkey2-14.2aux.1.1 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
do_test fkey2-14.2aux.1.2 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
} {{CREATE TABLE t1(a REFERENCES t2)}}
do_test fkey2-14.2aux.1.3 {
test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
# Test ALTER TABLE RENAME TABLE a bit.
#
do_test fkey2-14.2aux.2.1 {
drop_all_tables
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
@@ -120,12 +120,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
@@ -132,24 +132,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
@@ -158,52 +162,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);
@@ -222,6 +241,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: test/without_rowid3.test
==================================================================
--- test/without_rowid3.test
+++ test/without_rowid3.test
@@ -951,19 +951,21 @@
proc test_rename_parent {zCreate zOld zNew} {
db eval {SELECT sqlite_rename_table(
'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
)}
}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test without_rowid3-14.2.1.1 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
do_test without_rowid3-14.2.1.2 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
} {{CREATE TABLE t1(a REFERENCES t2)}}
do_test without_rowid3-14.2.1.3 {
test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
# Test ALTER TABLE RENAME TABLE a bit.
#
do_test without_rowid3-14.2.2.1 {
drop_all_tables
@@ -1035,19 +1037,21 @@
PRAGMA foreign_keys = on;
SELECT sql FROM temp.sqlite_master WHERE name='t2';
}
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test without_rowid3-14.2tmp.1.1 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
do_test without_rowid3-14.2tmp.1.2 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
} {{CREATE TABLE t1(a REFERENCES t2)}}
do_test without_rowid3-14.2tmp.1.3 {
test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
# Test ALTER TABLE RENAME TABLE a bit.
#
do_test without_rowid3-14.2tmp.2.1 {
drop_all_tables
@@ -1120,19 +1124,21 @@
PRAGMA foreign_keys = on;
SELECT sql FROM aux.sqlite_master WHERE name='t2';
}
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
do_test without_rowid3-14.2aux.1.1 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
do_test without_rowid3-14.2aux.1.2 {
test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
} {{CREATE TABLE t1(a REFERENCES t2)}}
do_test without_rowid3-14.2aux.1.3 {
test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
} {{CREATE TABLE t1(a REFERENCES "t3")}}
+ sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
# Test ALTER TABLE RENAME TABLE a bit.
#
do_test without_rowid3-14.2aux.2.1 {
drop_all_tables
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);