diff --git a/Makefile.msc b/Makefile.msc
index a3a1d52f79..8289068002 100644
--- a/Makefile.msc
+++ b/Makefile.msc
@@ -219,27 +219,43 @@ SQLITE3H = sqlite3.h
# This is the name to use for the SQLite dynamic link library (DLL).
#
!IFNDEF SQLITE3DLL
+!IF $(FOR_WIN10)!=0
+SQLITE3DLL = winsqlite3.dll
+!ELSE
SQLITE3DLL = sqlite3.dll
!ENDIF
+!ENDIF
# This is the name to use for the SQLite import library (LIB).
#
!IFNDEF SQLITE3LIB
+!IF $(FOR_WIN10)!=0
+SQLITE3LIB = winsqlite3.lib
+!ELSE
SQLITE3LIB = sqlite3.lib
!ENDIF
+!ENDIF
# This is the name to use for the SQLite shell executable (EXE).
#
!IFNDEF SQLITE3EXE
+!IF $(FOR_WIN10)!=0
+SQLITE3EXE = winsqlite3shell.exe
+!ELSE
SQLITE3EXE = sqlite3.exe
!ENDIF
+!ENDIF
# This is the argument used to set the program database (PDB) file for the
# SQLite shell executable (EXE).
#
!IFNDEF SQLITE3EXEPDB
+!IF $(FOR_WIN10)!=0
+SQLITE3EXEPDB =
+!ELSE
SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
!ENDIF
+!ENDIF
# These are the "standard" SQLite compilation options used when compiling for
# the Windows platform.
@@ -417,15 +433,6 @@ TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
-# Adjust the names of the primary targets for use with Windows 10.
-#
-!IF $(FOR_WIN10)!=0
-SQLITE3DLL = winsqlite3.dll
-SQLITE3LIB = winsqlite3.lib
-SQLITE3EXE = winsqlite3shell.exe
-SQLITE3EXEPDB =
-!ENDIF
-
# Check if we want to use the "stdcall" calling convention when compiling.
# This is not supported by the compilers for non-x86 platforms. It should
# also be noted here that building any target with these "stdcall" options
@@ -1411,10 +1418,10 @@ dll: $(SQLITE3DLL)
#
shell: $(SQLITE3EXE)
+# <>
libsqlite3.lib: $(LIBOBJ)
$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
-# <>
libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib
$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
# <>
@@ -2058,7 +2065,8 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H
clean:
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
- del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
+ del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
+ del /Q $(SQLITE3EXE) $(SQLITE3DLL) 2>NUL
# <>
del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL
del /Q lemon.* lempar.c parse.* 2>NUL
@@ -2078,7 +2086,6 @@ clean:
del /Q changeset.exe 2>NUL
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
- del /Q $(SQLITE3EXE) $(SQLITE3DLL) sqlite3.def 2>NUL
del /Q sqlite3.c sqlite3-*.c 2>NUL
del /Q sqlite3rc.h 2>NUL
del /Q shell.c sqlite3ext.h 2>NUL
diff --git a/VERSION b/VERSION
index afad818663..92536a9e48 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.11.0
+3.12.0
diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc
index 0be42b4e5f..52f0d91e0c 100644
--- a/autoconf/Makefile.msc
+++ b/autoconf/Makefile.msc
@@ -204,27 +204,43 @@ SQLITE3H = sqlite3.h
# This is the name to use for the SQLite dynamic link library (DLL).
#
!IFNDEF SQLITE3DLL
+!IF $(FOR_WIN10)!=0
+SQLITE3DLL = winsqlite3.dll
+!ELSE
SQLITE3DLL = sqlite3.dll
!ENDIF
+!ENDIF
# This is the name to use for the SQLite import library (LIB).
#
!IFNDEF SQLITE3LIB
+!IF $(FOR_WIN10)!=0
+SQLITE3LIB = winsqlite3.lib
+!ELSE
SQLITE3LIB = sqlite3.lib
!ENDIF
+!ENDIF
# This is the name to use for the SQLite shell executable (EXE).
#
!IFNDEF SQLITE3EXE
+!IF $(FOR_WIN10)!=0
+SQLITE3EXE = winsqlite3shell.exe
+!ELSE
SQLITE3EXE = sqlite3.exe
!ENDIF
+!ENDIF
# This is the argument used to set the program database (PDB) file for the
# SQLite shell executable (EXE).
#
!IFNDEF SQLITE3EXEPDB
+!IF $(FOR_WIN10)!=0
+SQLITE3EXEPDB =
+!ELSE
SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
!ENDIF
+!ENDIF
# These are the "standard" SQLite compilation options used when compiling for
# the Windows platform.
@@ -402,15 +418,6 @@ TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -fp:precise
RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
-# Adjust the names of the primary targets for use with Windows 10.
-#
-!IF $(FOR_WIN10)!=0
-SQLITE3DLL = winsqlite3.dll
-SQLITE3LIB = winsqlite3.lib
-SQLITE3EXE = winsqlite3shell.exe
-SQLITE3EXEPDB =
-!ENDIF
-
# Check if we want to use the "stdcall" calling convention when compiling.
# This is not supported by the compilers for non-x86 platforms. It should
# also be noted here that building any target with these "stdcall" options
@@ -863,7 +870,7 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_
# This is the default Makefile target. The objects listed here
# are what get build when you type just "make" with no arguments.
#
-all: dll libsqlite3.lib shell
+all: dll shell
# Dynamic link library section.
#
@@ -873,9 +880,6 @@ dll: $(SQLITE3DLL)
#
shell: $(SQLITE3EXE)
-libsqlite3.lib: $(LIBOBJ)
- $(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
-
$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
@@ -918,4 +922,5 @@ $(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
clean:
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
- del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
+ del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
+ del /Q $(SQLITE3EXE) $(SQLITE3DLL) 2>NUL
diff --git a/configure b/configure
index b2cb4d1308..09fba81eae 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.11.0.
+# Generated by GNU Autoconf 2.69 for sqlite 3.12.0.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.11.0'
-PACKAGE_STRING='sqlite 3.11.0'
+PACKAGE_VERSION='3.12.0'
+PACKAGE_STRING='sqlite 3.12.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1460,7 +1460,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sqlite 3.11.0 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.12.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1525,7 +1525,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.11.0:";;
+ short | recursive ) echo "Configuration of sqlite 3.12.0:";;
esac
cat <<\_ACEOF
@@ -1646,7 +1646,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.11.0
+sqlite configure 3.12.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2065,7 +2065,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sqlite $as_me 3.11.0, which was
+It was created by sqlite $as_me 3.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12079,7 +12079,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sqlite $as_me 3.11.0, which was
+This file was extended by sqlite $as_me 3.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12145,7 +12145,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sqlite config.status 3.11.0
+sqlite config.status 3.12.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/doc/lemon.html b/doc/lemon.html
index b16e35960e..2b8c613640 100644
--- a/doc/lemon.html
+++ b/doc/lemon.html
@@ -161,8 +161,9 @@ such as ``identifier'' or ``number'' and the third argument will
be the name of the identifier or the value of the number.
The Parse() function may have either three or four arguments,
-depending on the grammar. If the grammar specification file request
-it, the Parse() function will have a fourth parameter that can be
+depending on the grammar. If the grammar specification file requests
+it (via the extra_argument directive),
+the Parse() function will have a fourth parameter that can be
of any type chosen by the programmer. The parser doesn't do anything
with this argument except to pass it through to action routines.
This is a convenient mechanism for passing state information down
@@ -263,6 +264,12 @@ with prior yacc and bison experience.
But after years of experience using Lemon, I firmly
believe that the Lemon way of doing things is better.
+Updated as of 2016-02-16:
+The text above was written in the 1990s.
+We are told that Bison has lately been enhanced to support the
+tokenizer-calls-parser paradigm used by Lemon, and to obviate the
+need for global variables.
+
Input File Syntax
The main purpose of the grammar specification file for Lemon is
@@ -617,6 +624,7 @@ build a parser using Lemon that can be used within a long-running
program, such as a GUI, that will not leak memory or other resources.
To do the same using yacc or bison is much more difficult.
+
The %extra_argument directive
The %extra_argument directive instructs Lemon to add a 4th parameter
diff --git a/ext/fts3/fts3_test.c b/ext/fts3/fts3_test.c
index 36dcc94e6d..dec977b916 100644
--- a/ext/fts3/fts3_test.c
+++ b/ext/fts3/fts3_test.c
@@ -526,7 +526,8 @@ static int fts3_test_varint_cmd(
#ifdef SQLITE_ENABLE_FTS3
char aBuf[24];
int rc;
- Tcl_WideInt w, w2;
+ Tcl_WideInt w;
+ sqlite3_int64 w2;
int nByte, nByte2;
if( objc!=2 ){
diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c
index c40ffbcbb5..57d242bc3c 100644
--- a/ext/fts5/fts5_index.c
+++ b/ext/fts5/fts5_index.c
@@ -865,7 +865,7 @@ static int fts5StructureDecode(
for(iLvl=0; rc==SQLITE_OK && iLvlaLevel[iLvl];
- int nTotal;
+ int nTotal = 0;
int iSeg;
if( i>=nData ){
diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c
index fe1d72e2b0..28f3f3e62c 100644
--- a/ext/fts5/fts5_main.c
+++ b/ext/fts5/fts5_main.c
@@ -2665,6 +2665,17 @@ static int fts5Init(sqlite3 *db){
);
}
}
+
+ /* If SQLITE_FTS5_ENABLE_TEST_MI is defined, assume that the file
+ ** fts5_test_mi.c is compiled and linked into the executable. And call
+ ** its entry point to enable the matchinfo() demo. */
+#ifdef SQLITE_FTS5_ENABLE_TEST_MI
+ if( rc==SQLITE_OK ){
+ extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
+ rc = sqlite3Fts5TestRegisterMatchinfo(db);
+ }
+#endif
+
return rc;
}
diff --git a/ext/fts5/fts5_test_mi.c b/ext/fts5/fts5_test_mi.c
index 28331773c0..bc6d01f126 100644
--- a/ext/fts5/fts5_test_mi.c
+++ b/ext/fts5/fts5_test_mi.c
@@ -41,16 +41,17 @@
*/
-#ifdef SQLITE_TEST
#ifdef SQLITE_ENABLE_FTS5
#include "fts5.h"
-#include
#include
#include
typedef struct Fts5MatchinfoCtx Fts5MatchinfoCtx;
+
+#ifndef SQLITE_AMALGAMATION
typedef unsigned int u32;
+#endif
struct Fts5MatchinfoCtx {
int nCol; /* Number of cols in FTS5 table */
@@ -244,11 +245,7 @@ static int fts5MatchinfoLocalCb(
iOff>=0;
pApi->xPhraseNext(pFts, &iter, &iCol, &iOff)
){
- if( f=='b' ){
- aOut[iPhrase * ((p->nCol+31)/32) + iCol/32] |= ((u32)1 << iCol%32);
- }else{
- aOut[nMul * (iCol + iPhrase * p->nCol)]++;
- }
+ aOut[nMul * (iCol + iPhrase * p->nCol)]++;
}
}
@@ -409,7 +406,7 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
**
** Also check that the fts5_api object is version 2 or newer.
*/
- if( pApi==0 || pApi->iVersion<1 ){
+ if( pApi==0 || pApi->iVersion<2 ){
return SQLITE_ERROR;
}
@@ -420,5 +417,4 @@ int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
}
#endif /* SQLITE_ENABLE_FTS5 */
-#endif /* SQLITE_TEST */
diff --git a/ext/fts5/fts5parse.y b/ext/fts5/fts5parse.y
index 43936767b7..2bdf4b09b2 100644
--- a/ext/fts5/fts5parse.y
+++ b/ext/fts5/fts5parse.y
@@ -34,7 +34,6 @@
);
}
%stack_overflow {
- UNUSED_PARAM(yypMinor); /* Silence a compiler warning */
sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
}
diff --git a/ext/fts5/test/fts5faultB.test b/ext/fts5/test/fts5faultB.test
new file mode 100644
index 0000000000..40df8b6043
--- /dev/null
+++ b/ext/fts5/test/fts5faultB.test
@@ -0,0 +1,83 @@
+# 2016 February 17
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#*************************************************************************
+#
+# This file is focused on OOM errors.
+#
+
+source [file join [file dirname [info script]] fts5_common.tcl]
+source $testdir/malloc_common.tcl
+set testprefix fts5faultB
+
+# If SQLITE_ENABLE_FTS3 is defined, omit this file.
+ifcapable !fts5 {
+ finish_test
+ return
+}
+
+proc mit {blob} {
+ set scan(littleEndian) i*
+ set scan(bigEndian) I*
+ binary scan $blob $scan($::tcl_platform(byteOrder)) r
+ return $r
+}
+db func mit mit
+
+
+#-------------------------------------------------------------------------
+# Errors while registering the matchinfo() demo function.
+#
+do_faultsim_test 1 -faults oom* -prep {
+ sqlite3 db test.db
+} -body {
+ sqlite3_fts5_register_matchinfo db
+} -test {
+ faultsim_test_result {0 {}} {1 SQLITE_ERROR} {1 SQLITE_NOMEM}
+}
+
+
+#-------------------------------------------------------------------------
+# Errors while executing the matchinfo() demo function.
+#
+reset_db
+sqlite3_fts5_register_matchinfo db
+db func mit mit
+do_execsql_test 2 {
+ CREATE VIRTUAL TABLE t1 USING fts5(a, b);
+ INSERT INTO t1 VALUES('x y z', '1 2 3');
+ INSERT INTO t1 VALUES('x', '1 2 3 4 5 6 7');
+}
+
+do_faultsim_test 2.1 -faults oom* -body {
+ execsql { SELECT mit(matchinfo(t1, 'a')) FROM t1('x') }
+} -test {
+ faultsim_test_result {0 {{2 5} {2 5}}}
+}
+
+do_faultsim_test 2.2 -faults oom* -body {
+ execsql { SELECT mit(matchinfo(t1, 'l')) FROM t1('x') }
+} -test {
+ faultsim_test_result {0 {{3 3} {1 7}}}
+}
+
+do_execsql_test 2.3 {
+ INSERT INTO t1 VALUES('a b c d e f', 'a b d e f c');
+ INSERT INTO t1 VALUES('l m b c a', 'n o a b c z');
+}
+
+do_faultsim_test 2.4 -faults oom* -body {
+ execsql { SELECT mit(matchinfo(t1, 's')) FROM t1('a b c') }
+} -test {
+ faultsim_test_result {0 {{3 2} {2 3}}}
+}
+
+
+finish_test
+
diff --git a/ext/fts5/test/fts5matchinfo.test b/ext/fts5/test/fts5matchinfo.test
index 06f4550b47..99b07677af 100644
--- a/ext/fts5/test/fts5matchinfo.test
+++ b/ext/fts5/test/fts5matchinfo.test
@@ -467,5 +467,29 @@ do_execsql_test 12.1 {
} ;# foreach_detail_mode
+#-------------------------------------------------------------------------
+# Test that a bad fts5() return is detected
+#
+reset_db
+proc xyz {} {}
+db func fts5 -argcount 0 xyz
+do_test 13.1 {
+ list [catch { sqlite3_fts5_register_matchinfo db } msg] $msg
+} {1 SQLITE_ERROR}
+
+#-------------------------------------------------------------------------
+# Test that an invalid matchinfo() flag is detected
+#
+reset_db
+sqlite3_fts5_register_matchinfo db
+do_execsql_test 14.1 {
+ CREATE VIRTUAL TABLE x1 USING fts5(z);
+ INSERT INTO x1 VALUES('a b c a b c a b c');
+} {}
+
+do_catchsql_test 14.2 {
+ SELECT matchinfo(x1, 'd') FROM x1('a b c');
+} {1 {unrecognized matchinfo flag: d}}
+
finish_test
diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c
index 145b446d30..682becbb5c 100644
--- a/ext/rbu/sqlite3rbu.c
+++ b/ext/rbu/sqlite3rbu.c
@@ -3704,7 +3704,7 @@ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){
static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){
rbu_file *pDb;
sqlite3_mutex_enter(pRbuVfs->mutex);
- for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext);
+ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){}
sqlite3_mutex_leave(pRbuVfs->mutex);
return pDb;
}
diff --git a/manifest b/manifest
index cdce0eb4b0..0cea1da469 100644
--- a/manifest
+++ b/manifest
@@ -1,17 +1,17 @@
-C Merge\s3.11.0\schanges.
-D 2016-02-15T17:39:10.662
+C Merge\sall\sthe\slatest\schanges\sfrom\strunk.
+D 2016-02-25T18:54:30.918
F Makefile.in 5cbf3f753328d1bcd3a6117785b4874d99612f8f
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
-F Makefile.msc 45e596bd4ccecf2256f68a2e96466aa52cc4bc1f
+F Makefile.msc cf5496f4c4e256a79bae1804da61703647b26398
F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7
-F VERSION 866588d1edf0ccb5b0d33896974338f97564f719
+F VERSION c6b1f51809551d60ad001e6d87cf3ab2c7f54b6f
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am 29e2a6e8d0c5e32723a48b4faf6b168854dde5f4
-F autoconf/Makefile.msc b865d2c72cf43cbf39913336415556af8ff2e819
+F autoconf/Makefile.msc d5ab32cf30d6ba8b5ce20835b4042f6cc2a4cb39
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 7c31da66232f7590bb987cfcd4e2381744b25d24
F autoconf/configure.ac 72a5e42beb090b32bca580285dc0ab3c4670adb8
@@ -30,10 +30,10 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
-F configure 12d96e3798e612e0ffa53a7a8c4d7fb1090df80e x
+F configure 0339a635cd2943a3b56000a10a11b4b2e6ed6d1b x
F configure.ac a2224b1162f79848982d3618ac1deffcd94e88ec
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
-F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
+F doc/lemon.html c30255bea0fd87a81f082d17a72c9dffbc3f6dd9
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
@@ -81,7 +81,7 @@ F ext/fts3/fts3_icu.c deb46f7020d87ea7a14a433fb7a7f4bef42a9652
F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009
F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e
F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7
-F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
+F ext/fts3/fts3_test.c 11e36437b0f3f2266acea5b4787f615e4337a237
F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860
F ext/fts3/fts3_tokenizer.c 4bd72f767f61c9ce5a7575c844e8d1ed2c3c561a
F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
@@ -104,17 +104,17 @@ F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
F ext/fts5/fts5_config.c 35c5173cae4eb17e82164a7f5aeef56a48903079
F ext/fts5/fts5_expr.c 8e8e4635f655133eb39018072fc0f0942a2c4337
F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
-F ext/fts5/fts5_index.c c6cd5190c7e5dd94151cb17acd939c82e5c7be2d
-F ext/fts5/fts5_main.c 0e01ead4e817483e378e7e38e6d902f50b68d29e
+F ext/fts5/fts5_index.c 78069efb54559a17c35906a741362d0b5c899bd0
+F ext/fts5/fts5_main.c db24ac714c6c4a1b3c24a1f8c25889f2952148c1
F ext/fts5/fts5_storage.c f8343db90d8c95a4d4b52f6676e354b4649ffd6e
F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
-F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070
+F ext/fts5/fts5_test_mi.c b8d04816428202b2898d4ca38deb1739ac0110ae
F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf
F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738
F ext/fts5/fts5_vocab.c dba72ca393d71c2588548b51380387f6b44c77a8
-F ext/fts5/fts5parse.y 59432ea369f1aa65511bad465f55d31a22f9f223
+F ext/fts5/fts5parse.y 86fe6ba094a47e02fe8be2571539e6833d197764
F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba
F ext/fts5/test/fts5_common.tcl 61ff0d1a29d98a91c4553b20b3f410d858834ee9
F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084
@@ -157,10 +157,11 @@ F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080
F ext/fts5/test/fts5fault8.test 430837fe6dd0511fd3aea52bd602ac02441bcb58
F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
+F ext/fts5/test/fts5faultB.test 92ae906284062bf081b6c854afa54dcb1aa9ef88
F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d
-F ext/fts5/test/fts5matchinfo.test 86569026d20f1ed748236587ce798de8a96615f1
+F ext/fts5/test/fts5matchinfo.test f7dde99697bcb310ea8faa8eb2714d9f4dfc0e1b
F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367
F ext/fts5/test/fts5merge2.test c0cb66eb38a41c26cc5848fb9e50093e0f59ac93
F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc
@@ -240,7 +241,7 @@ F ext/rbu/rbufault.test cc0be8d5d392d98b0c2d6a51be377ea989250a89
F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06
F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda
F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
-F ext/rbu/sqlite3rbu.c bea954197524631f2691ec272e8a42df8cad01cc
+F ext/rbu/sqlite3rbu.c 371e8bf06cfb3f691adac47eb15ab1073ed92dcf
F ext/rbu/sqlite3rbu.h 0bdeb3be211aaba7d85445fa36f4701a25a3dbde
F ext/rbu/test_rbu.c 4a4cdcef4ef9379fc2a21f008805c80b27bcf573
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
@@ -304,43 +305,43 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c 1fbb01c26c64528088f1df8015992fefda387889
-F src/analyze.c fbf0e80d83cc893734e872f932f249a056b86e11
-F src/attach.c c16c2648a577fa3def2adfa48c28901376389bc5
+F src/alter.c 7603afbd61f55e7c644b8de4a42f33e58c0b7eaa
+F src/analyze.c ab57b6763dd4c6170a20673d14882c033affd188
+F src/attach.c a3724c64de1099d85e30751213d285752aed9505
F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
-F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc
-F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf
+F src/backup.c f60f0aa55d25d853ffde53d0b0370a7bb7ee41ce
+F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
-F src/btree.c 4c8caaeed7878aafdb607c3d2bcbc365bb0d19a1
-F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e
+F src/btree.c 7bb920c473c277380fcb3e8a8ee28ce1a48e0abc
+F src/btree.h a5008b9afe56e8e54ade6c436a910f112defcca9
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
-F src/build.c 54866fbafa09d494269bdefc79995eb7207003a6
-F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce
-F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f
+F src/build.c 6661513c8f90a23d44ed5e5ada7ea40fac6b6b77
+F src/callback.c 2e76147783386374bf01b227f752c81ec872d730
+F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198
-F src/date.c ca17321bc17cca8f40e0843edea4fafff974998e
-F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c
+F src/date.c 0b73e681c11fca867fec554750c07fe0d4e417c1
+F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b
F src/delete.c eeac28b3d3d88e3541bdf93e91ea7492a7b67842
-F src/expr.c fbf0706199aea23c54efe36b6932d8307c4eb872
+F src/expr.c 9adb58153f6e943b703d43e9a1f67f77b5a75721
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 08edad1fce30f761f14b3997e89bad58f9f7f4e0
-F src/func.c 86e55fee35b9577e485f47d9dd5c1d34cd513288
-F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260
+F src/func.c 552d300265aed09eea21f68ac742a440550c0062
+F src/global.c ded7b97efd16efda5062b65e857198e46c40e652
F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5
F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c d53917351d0542ce2be88888dca6b0b076e46aaa
-F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
-F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902
-F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b
-F src/main.c 411d1dbe085a45f323e3bd8fed91da06cedb4c3b
-F src/malloc.c 337e9808b5231855fe28857950f4f60ae42c417f
+F src/journal.c fe3a3e2559ce3ce9d371afd30fbabbc074174575
+F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
+F src/loadext.c 9e2a41adcaff16ebc1ebff1f336cbf33de55396f
+F src/main.c 254cb296471997935fade3aeefb4618941a330ea
+F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3
F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a
F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944
-F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85
+F src/memjournal.c 349a04fb803db40532cde0993e39758f1acaecce
F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495
F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c
F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85
@@ -348,37 +349,37 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
F src/mutex_unix.c 27bb6cc49485ee46711a6580ab7b3f1402211d23
F src/mutex_w32.c 5e6fe1c298fb5a8a15aaed4161d5759311431c17
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
-F src/os.c 205fa2bad945a0dc7cad48f9f95ea3e8dc5408ff
+F src/os.c ca9a104b677328ee037cfdf1a54a16fd1805e8c9
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
-F src/os_unix.c 821ed110197175165cf2f50b0930c7ff9a24504c
-F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2
+F src/os_unix.c 3a6f20736dfb8a0949cdd66553fdf59f6604be35
+F src/os_win.c f0d7aa603eb6262143d7169a222aea07c4fca91d
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
-F src/pager.c 67cd2fbab58d0e35fed5f81432856f4f0af9fc6d
-F src/pager.h f3eb324a3ff2408b28bab7e81c1c55c13720f865
-F src/parse.y d7bff41d460f2df96fb890f36700e85cb0fc5634
-F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23
+F src/pager.c d034c69b958c01289eb8070cbf902e1a68cd7e0b
+F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
+F src/parse.y c3ce2c4a7cbf0b699239be6b2a945c5cb51875e2
+F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051
F src/pragma.c 80ee77226d0008d9188356a6cbbe6010866e1bee
F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c
-F src/prepare.c c12b786713df3e8270c0f85f988c5359d8b4d87c
+F src/prepare.c 22df6171aec1d86904ed2ad30c2348a5748aa04e
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
-F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c
+F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e
-F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d
-F src/shell.c 8cb62662c93e75189a152c4896336f44f05ced28
-F src/sqlite.h.in 9a3a1ee60bd2681034a3b730ef1208268d00fcc8
+F src/select.c dbc73a63bee99bf7cfac6052477ffc21e899bb08
+F src/shell.c 529ff15fbafe9f698e0cb8f9f16d0ce5106fd6e9
+F src/sqlite.h.in ba31c7deaa59bc9a282239d9e39d918c6a2b346d
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d
-F src/sqliteInt.h a6127f268ee02e6f792e5d5706707a8dd9bf8808
+F src/sqliteInt.h 73f110a751b8e24e2e0c6020d761c16ad23acaff
F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46
F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba
-F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e
+F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
F src/tclsqlite.c 89b27573473e94257d9a2d296bc6c0626c9314d0
-F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7
+F src/test1.c 8b17b1ff53aad71e7f9318a2fda247beddeaa601
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
@@ -390,12 +391,12 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8
F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12
F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803
-F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07
+F src/test_blob.c b2551a9b5573232db5f66f292307c37067937239
F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f
F src/test_config.c 1e51263265c5b78adca10fa204d1e6f164387a20
F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
-F src/test_fs.c a61f54247fdb843761d709879c3bcd1989b2050c
+F src/test_fs.c f10f840ca4f8c72e4837908bd8347ac4bcab074b
F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
@@ -425,32 +426,32 @@ F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61
F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
-F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0
-F src/tokenize.c 813934be70597edfbb685ae08fc4c8b549cf5a1e
-F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b
+F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
+F src/tokenize.c 3d338cdd00d916ce8a05c397001d64ed58e6fe1c
+F src/treeview.c c525282442111b3f61eb176784567cd6654db5dc
F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
F src/update.c c0016d277a418360456ff6af29363effbd4272f7
-F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18
-F src/util.c 49ce0a65306c1c51d61cb5bc214c71cb62452de6
-F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701
-F src/vdbe.c 830c927c64e477f86f33d806c585ab1904cf6e4e
+F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
+F src/util.c 38c06684c922694809ccb988a13562c16890a3d5
+F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
+F src/vdbe.c 9ccb138cb7ac6c1bcda23dfaf52eff1f7761dfe5
F src/vdbe.h 594aef1a7dcfc2944e2f266f148140c3427fd0f0
-F src/vdbeInt.h 2a8796b099a463cf6c32514f8aa138d3b0c36b23
-F src/vdbeapi.c f9bed48c23da6487fbe6648df45f340ccc199c4f
-F src/vdbeaux.c 520bf491dcf75ce8944c9486ac7e2fc68d1ea5a4
+F src/vdbeInt.h 177eca5abb111140d06a149d8c3ae40f9f2eb4fc
+F src/vdbeapi.c ba85b78fe08dc4a9ce747e62c89a2b4a4547e74c
+F src/vdbeaux.c 325dcf1b944e6d339a5c5210b7b8c5724a8496fb
F src/vdbeblob.c c9f2f494b911c6fa34efd9803f0a10807da80f77
-F src/vdbemem.c 36e2779132eaff83c7ed44d76340b8d2caab17cf
-F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174
+F src/vdbemem.c c2a7c2ece87b40f1e1345c07412f2143c05eee85
+F src/vdbesort.c 307460bfa4de4d1c3901fcd42089159131e34062
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484
-F src/vtab.c bef51b4f693d82b4b0184457faa8625654534091
+F src/vtab.c 943c23b355f0a8f859f9583e7315d64bebdb0899
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 1dd3f1aeed5765be62f27d7d2e44d46a68d891ab
+F src/wal.c 10deb6b43887662691e5f53d10b3c171c401169b
F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
-F src/where.c 984084584c10c41e46c89ac027a5cca991bc37e6
-F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a
-F src/wherecode.c 791a784bbf8749d560fdb0b990b607bc4f44a38d
-F src/whereexpr.c de117970b29471177a6901d60ad83a194671dc03
+F src/where.c b21a2b3cee42e1db4f14c8fc5124f607e0c668c0
+F src/whereInt.h 93297d56edd137b7ea004490690fb6e2ce028a34
+F src/wherecode.c 39c1ef4598bedf1d66249334c74efd23ddd182ac
+F src/whereexpr.c fb87944b1254234e5bba671aaf6dee476241506a
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -494,7 +495,7 @@ F test/auth2.test 264c6af53cad9aba5218c68bbe18036e39007bfa
F test/auth3.test 5cfa94ed90c6617c42b7ba4b133fd79678b251c7
F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7
F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea
-F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8
+F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df
F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972
F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf
F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990
@@ -583,7 +584,7 @@ F test/corruptI.test 347babbf970e7947e3f91dccf7a1bec28a1bab04
F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91
F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8
F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c
-F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62
+F test/coveridxscan.test b629e896b14df2f000a99b8d170d80589c46562c
F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f
F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651
F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418
@@ -784,7 +785,7 @@ F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1
F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5
F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b
F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26
-F test/fuzzcheck.c 3309d793165ca61a9996271cb799694839348f9a
+F test/fuzzcheck.c 93bb9d309888634615e21ef98d1c30d51483e942
F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664
F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973
F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba
@@ -875,7 +876,7 @@ F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035
F test/lookaside.test 90052e87282de256d613fcf8c9cbb845e4001d2f
-F test/main.test 16131264ea0c2b93b95201f0c92958e85f2ba11a
+F test/main.test bb75e406c9b64931f3dc7e7f04626633365bb22f
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/malloc.test 21c213365f2cca95ab2d7dc078dc8525f96065f8
F test/malloc3.test e3b32c724b5a124b57cb0ed177f675249ad0c66a
@@ -909,7 +910,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
-F test/misc1.test 48ebfb5b22a6a058f7b7e1df211226dd1d21409c
+F test/misc1.test 6430dabfb4b4fa480633590118964201f94d3ccc
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 0d8be3466adf123a7791a66ba2bc8e8d229e87f3
@@ -951,7 +952,7 @@ F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
-F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa
+F test/pager1.test f49df1a8b0e38b9ee3a7dd2ab4d427507b7314ce
F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71
F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
F test/pager4.test a122e9e6925d5b23b31e3dfef8c6a44bbf19590e
@@ -983,6 +984,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
+F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl 975449bf742b8bb9025208292208af816a1fcb58
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
@@ -1071,7 +1073,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
-F test/speedtest1.c f8bf04214e7b5f745feea99f7bde68b1c4870666
+F test/speedtest1.c 947421c324f5cd4cb3dcae1ec214e4be763df718
F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db
F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3
F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97
@@ -1099,7 +1101,7 @@ F test/tclsqlite.test 7179b4e0bf236ddf0bfa6bfaefa76fbe0a23c28a
F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
-F test/tester.tcl d8ef0a5ab95b16fefd7123f38647114c34b0c9b7
+F test/tester.tcl 9310df7ac540d4e97d8fa4a9605a639801ede65f
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@@ -1388,7 +1390,7 @@ F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372
F tool/addopcodes.tcl 4ca9c3ef196f08da30add5d07ce0c9458dc8c633
-F tool/build-all-msvc.bat 31866578036cd1d962628059b0760d407c3ce4d8 x
+F tool/build-all-msvc.bat 55be1cf8545dabd69df2ba6b3de6868da0c26f52 x
F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367
F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
@@ -1399,13 +1401,13 @@ F tool/fuzzershell.c 94019b185caceffc9f7c7b678a6489e42bc2aefa
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
-F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d
-F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7
+F tool/lemon.c 251f5c3f21b553240cbdd42dd187a51bb2372cd3
+F tool/lempar.c d5114c7d13aa3af1e27ff3d02e4dea6eadec7ddf
F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh c78caa3214f25dc28ea157b5a82abb311f209906
F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22
-F tool/mkmsvcmin.tcl d57e6efc9428605f5418d0b235721ddf7b5d9c0b
+F tool/mkmsvcmin.tcl f9fc6f6a373084c0e0feef972485212bd0869c06
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
@@ -1415,7 +1417,7 @@ F tool/mksqlite3c-noext.tcl 87240b09c20042999b41d5fabe091b7111287835
F tool/mksqlite3c.tcl a52d7e8c0888f9384fbfa2c6ddd5f357409758b9
F tool/mksqlite3h.tcl e7b106fc4f29fbc258e8ba9b88d9108332ea2ade
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
-F tool/mkvsix.tcl fbeb0af7cffdf64e0fba6d65e2e5120dc14595f4
+F tool/mkvsix.tcl 4abcaf3267171b2faadaf9b82a0dfbaa6e98f8b7
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
F tool/omittest.tcl 34d7ac01fe4fd18e3637f64abe12c40eca0f6b97
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
@@ -1446,9 +1448,9 @@ F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl 5926c71f9c12d2ab73ef35c29376e756eb68361c
F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
-F tool/warnings.sh ef6ebc6fd8d2dc35db3b622015c16a023d4fef4f
+F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P f6d1cf79437f892220e93635c377513160ee7fd7 3d862f207e3adc00f78066799ac5a8c282430a5f
-R b476bf4ab3b143a25fb59e5c7bd22337
+P 631023dd9aa19cd8d92d712941d58e7148821995 bf46179d4484376909dce40ffcc06fecb19b3544
+R 7e6dc514e3703b1055f28159276cc00f
U drh
-Z a1cb35e211e072ee0c64a1a99f864eec
+Z d59a306a1e57a2c5fa67f4c507e15fb8
diff --git a/manifest.uuid b/manifest.uuid
index 2fbe2597df..fa6b7d256f 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-631023dd9aa19cd8d92d712941d58e7148821995
\ No newline at end of file
+b86590043e17705ada90562cf30f69b3e3ef65a4
\ No newline at end of file
diff --git a/src/alter.c b/src/alter.c
index 34221777a7..f10a85022a 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -229,7 +229,7 @@ static void renameTriggerFunc(
** Register built-in functions used to help implement ALTER TABLE
*/
void sqlite3AlterFunctions(void){
- static SQLITE_WSD FuncDef aAlterTableFuncs[] = {
+ static FuncDef aAlterTableFuncs[] = {
FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc),
#ifndef SQLITE_OMIT_TRIGGER
FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc),
@@ -238,13 +238,7 @@ void sqlite3AlterFunctions(void){
FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc),
#endif
};
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAlterTableFuncs);
-
- for(i=0; ilookaside.bDisable );
zSql = sqlite3MPrintf(db, zSql1, zDb);
if( !zSql ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
sqlite3DbFree(db, zSql);
@@ -1713,7 +1710,7 @@ static int loadStatTbl(
pIdx->aSample = sqlite3DbMallocZero(db, nByte);
if( pIdx->aSample==0 ){
sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
@@ -1729,7 +1726,7 @@ static int loadStatTbl(
zSql = sqlite3MPrintf(db, zSql2, zDb);
if( !zSql ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
sqlite3DbFree(db, zSql);
@@ -1767,7 +1764,7 @@ static int loadStatTbl(
pSample->p = sqlite3DbMallocZero(db, pSample->n + 2);
if( pSample->p==0 ){
sqlite3_finalize(pStmt);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n);
pIdx->nSample++;
@@ -1856,7 +1853,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
zSql = sqlite3MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
if( zSql==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
sqlite3DbFree(db, zSql);
diff --git a/src/attach.c b/src/attach.c
index 2288ac9b62..484a5a110c 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -144,7 +144,7 @@ static void attachFunc(
Pager *pPager;
aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
if( !aNew->pSchema ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
zErrDyn = sqlite3MPrintf(db,
"attached databases must use the same text encoding as main database");
@@ -164,7 +164,7 @@ static void attachFunc(
aNew->safety_level = 3;
aNew->zName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && aNew->zName==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
@@ -392,8 +392,7 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){
detachFunc, /* xSFunc */
0, /* xFinalize */
"sqlite_detach", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
}
@@ -412,8 +411,7 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
attachFunc, /* xSFunc */
0, /* xFinalize */
"sqlite_attach", /* zName */
- 0, /* pHash */
- 0 /* pDestructor */
+ {0}
};
codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
}
diff --git a/src/backup.c b/src/backup.c
index 1c282242d7..455671a1ad 100644
--- a/src/backup.c
+++ b/src/backup.c
@@ -88,7 +88,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
if( pParse==0 ){
sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pParse->db = pDb;
if( sqlite3OpenTempDatabase(pParse) ){
@@ -182,7 +182,7 @@ sqlite3_backup *sqlite3_backup_init(
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
- sqlite3Error(pDestDb, SQLITE_NOMEM);
+ sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
}
}
@@ -581,7 +581,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){
}
if( rc==SQLITE_IOERR_NOMEM ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
p->rc = rc;
}
diff --git a/src/bitvec.c b/src/bitvec.c
index f7f544cff7..9d13ba9185 100644
--- a/src/bitvec.c
+++ b/src/bitvec.c
@@ -177,7 +177,7 @@ int sqlite3BitvecSet(Bitvec *p, u32 i){
i = i%p->iDivisor;
if( p->u.apSub[bin]==0 ){
p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
- if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
+ if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT;
}
p = p->u.apSub[bin];
}
@@ -212,7 +212,7 @@ bitvec_set_rehash:
int rc;
u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
if( aiValues==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
memset(p->u.apSub, 0, sizeof(p->u.apSub));
diff --git a/src/btree.c b/src/btree.c
index c6f9c34f7b..036e63a016 100644
--- a/src/btree.c
+++ b/src/btree.c
@@ -350,7 +350,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
if( !pLock ){
pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock));
if( !pLock ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pLock->iTable = iTable;
pLock->pBtree = p;
@@ -553,7 +553,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){
assert( pgno<=pBt->nPage );
pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage);
if( !pBt->pHasContent ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){
@@ -632,7 +632,7 @@ static int saveCursorKey(BtCursor *pCur){
sqlite3_free(pKey);
}
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
assert( !pCur->curIntKey || !pCur->pKey );
@@ -764,7 +764,7 @@ static int btreeMoveto(
pIdxKey = sqlite3VdbeAllocUnpackedRecord(
pCur->pKeyInfo, aSpace, sizeof(aSpace), &pFree
);
- if( pIdxKey==0 ) return SQLITE_NOMEM;
+ if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT;
sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, pIdxKey);
if( pIdxKey->nField==0 ){
sqlite3DbFree(pCur->pKeyInfo->db, pFree);
@@ -2176,7 +2176,7 @@ int sqlite3BtreeOpen(
}
p = sqlite3MallocZero(sizeof(Btree));
if( !p ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
p->inTrans = TRANS_NONE;
p->db = db;
@@ -2200,7 +2200,7 @@ int sqlite3BtreeOpen(
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( isMemdb ){
memcpy(zFullPathname, zFilename, nFilename);
@@ -2268,7 +2268,7 @@ int sqlite3BtreeOpen(
pBt = sqlite3MallocZero( sizeof(*pBt) );
if( pBt==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
@@ -2337,7 +2337,7 @@ int sqlite3BtreeOpen(
if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
if( pBt->mutex==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto btree_open_out;
}
}
@@ -2619,21 +2619,6 @@ int sqlite3BtreeSetPagerFlags(
}
#endif
-/*
-** Return TRUE if the given btree is set to safety level 1. In other
-** words, return TRUE if no sync() occurs on the disk files.
-*/
-int sqlite3BtreeSyncDisabled(Btree *p){
- BtShared *pBt = p->pBt;
- int rc;
- assert( sqlite3_mutex_held(p->db->mutex) );
- sqlite3BtreeEnter(p);
- assert( pBt && pBt->pPager );
- rc = sqlite3PagerNosync(pBt->pPager);
- sqlite3BtreeLeave(p);
- return rc;
-}
-
/*
** Change the default pages size and the number of reserved bytes per page.
** Or, if the page size has already been fixed, return SQLITE_READONLY
@@ -4114,7 +4099,7 @@ static int btreeCursor(
if( wrFlag ){
allocateTempSpace(pBt);
- if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
+ if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
}
if( iTable==1 && btreePagecount(pBt)==0 ){
assert( wrFlag==0 );
@@ -4512,7 +4497,7 @@ static int accessPayload(
pCur->aOverflow, nOvfl*2*sizeof(Pgno)
);
if( aNew==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pCur->nOvflAlloc = nOvfl*2;
pCur->aOverflow = aNew;
@@ -5217,7 +5202,7 @@ int sqlite3BtreeMovetoUnpacked(
}
pCellKey = sqlite3Malloc( nCell+18 );
if( pCellKey==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto moveto_finish;
}
pCur->aiIdx[pCur->iPage] = (u16)idx;
@@ -7036,7 +7021,7 @@ static int balance_nonroot(
assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx );
if( !aOvflSpace ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* Find the sibling pages to balance. Also locate the cells in pParent
@@ -7136,7 +7121,7 @@ static int balance_nonroot(
assert( szScratch<=6*(int)pBt->pageSize );
b.apCell = sqlite3ScratchMalloc( szScratch );
if( b.apCell==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto balance_cleanup;
}
b.szCell = (u16*)&b.apCell[nMaxCells];
diff --git a/src/btree.h b/src/btree.h
index 30522e99e1..9ba233ac33 100644
--- a/src/btree.h
+++ b/src/btree.h
@@ -68,7 +68,6 @@ int sqlite3BtreeSetSpillSize(Btree*,int);
int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64);
#endif
int sqlite3BtreeSetPagerFlags(Btree*,unsigned);
-int sqlite3BtreeSyncDisabled(Btree*);
int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix);
int sqlite3BtreeGetPageSize(Btree*);
int sqlite3BtreeMaxPageCount(Btree*,int);
diff --git a/src/build.c b/src/build.c
index 250dc20d20..b14d45f6da 100644
--- a/src/build.c
+++ b/src/build.c
@@ -710,12 +710,8 @@ int sqlite3FindDbName(sqlite3 *db, const char *zName){
int i = -1; /* Database number */
if( zName ){
Db *pDb;
- int n = sqlite3Strlen30(zName);
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
- if( (!OMIT_TEMPDB || i!=1 ) && n==sqlite3Strlen30(pDb->zName) &&
- 0==sqlite3StrICmp(pDb->zName, zName) ){
- break;
- }
+ if( 0==sqlite3StrICmp(pDb->zName, zName) ) break;
}
}
return i;
@@ -927,7 +923,7 @@ void sqlite3StartTable(
pTable = sqlite3DbMallocZero(db, sizeof(Table));
if( pTable==0 ){
assert( db->mallocFailed );
- pParse->rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM_BKPT;
pParse->nErr++;
goto begin_table_error;
}
@@ -1608,7 +1604,7 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){
assert( pIdx->isResized==0 );
nByte = (sizeof(char*) + sizeof(i16) + 1)*N;
zExtra = sqlite3DbMallocZero(db, nByte);
- if( zExtra==0 ) return SQLITE_NOMEM;
+ if( zExtra==0 ) return SQLITE_NOMEM_BKPT;
memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn);
pIdx->azColl = (const char**)zExtra;
zExtra += sizeof(char*)*N;
@@ -3200,6 +3196,20 @@ Index *sqlite3CreateIndex(
sqlite3DefaultRowEst(pIndex);
if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
+ /* If this index contains every column of its table, then mark
+ ** it as a covering index */
+ assert( HasRowid(pTab)
+ || pTab->iPKey<0 || sqlite3ColumnOfIndex(pIndex, pTab->iPKey)>=0 );
+ if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){
+ pIndex->isCovering = 1;
+ for(j=0; jnCol; j++){
+ if( j==pTab->iPKey ) continue;
+ if( sqlite3ColumnOfIndex(pIndex,j)>=0 ) continue;
+ pIndex->isCovering = 0;
+ break;
+ }
+ }
+
if( pTab==pParse->pNewTable ){
/* This routine has been called to create an automatic index as a
** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
@@ -3237,7 +3247,7 @@ Index *sqlite3CreateIndex(
if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break;
z1 = pIdx->azColl[k];
z2 = pIndex->azColl[k];
- if( z1!=z2 && sqlite3StrICmp(z1, z2) ) break;
+ if( sqlite3StrICmp(z1, z2) ) break;
}
if( k==pIdx->nKeyCol ){
if( pIdx->onError!=pIndex->onError ){
diff --git a/src/callback.c b/src/callback.c
index 2b955fdcdb..2351178867 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -284,14 +284,12 @@ static int matchQuality(
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
static FuncDef *functionSearch(
- FuncDefHash *pHash, /* Hash table to search */
int h, /* Hash of the name */
- const char *zFunc, /* Name of function */
- int nFunc /* Number of bytes in zFunc */
+ const char *zFunc /* Name of function */
){
FuncDef *p;
- for(p=pHash->a[h]; p; p=p->pHash){
- if( sqlite3StrNICmp(p->zName, zFunc, nFunc)==0 && p->zName[nFunc]==0 ){
+ for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
+ if( sqlite3StrICmp(p->zName, zFunc)==0 ){
return p;
}
}
@@ -301,23 +299,26 @@ static FuncDef *functionSearch(
/*
** Insert a new FuncDef into a FuncDefHash hash table.
*/
-void sqlite3FuncDefInsert(
- FuncDefHash *pHash, /* The hash table into which to insert */
- FuncDef *pDef /* The function definition to insert */
+void sqlite3InsertBuiltinFuncs(
+ FuncDef *aDef, /* List of global functions to be inserted */
+ int nDef /* Length of the apDef[] list */
){
- FuncDef *pOther;
- int nName = sqlite3Strlen30(pDef->zName);
- u8 c1 = (u8)pDef->zName[0];
- int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash->a);
- pOther = functionSearch(pHash, h, pDef->zName, nName);
- if( pOther ){
- assert( pOther!=pDef && pOther->pNext!=pDef );
- pDef->pNext = pOther->pNext;
- pOther->pNext = pDef;
- }else{
- pDef->pNext = 0;
- pDef->pHash = pHash->a[h];
- pHash->a[h] = pDef;
+ int i;
+ for(i=0; ipNext!=&aDef[i] );
+ aDef[i].pNext = pOther->pNext;
+ pOther->pNext = &aDef[i];
+ }else{
+ aDef[i].pNext = 0;
+ aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h];
+ sqlite3BuiltinFunctions.a[h] = &aDef[i];
+ }
}
}
@@ -344,8 +345,7 @@ void sqlite3FuncDefInsert(
*/
FuncDef *sqlite3FindFunction(
sqlite3 *db, /* An open database */
- const char *zName, /* Name of the function. Not null-terminated */
- int nName, /* Number of characters in the name */
+ const char *zName, /* Name of the function. zero-terminated */
int nArg, /* Number of arguments. -1 means any number */
u8 enc, /* Preferred text encoding */
u8 createFlag /* Create new entry if true and does not otherwise exist */
@@ -354,14 +354,15 @@ FuncDef *sqlite3FindFunction(
FuncDef *pBest = 0; /* Best match found so far */
int bestScore = 0; /* Score of best match */
int h; /* Hash value */
+ int nName; /* Length of the name */
assert( nArg>=(-2) );
assert( nArg>=(-1) || createFlag==0 );
- h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
+ nName = sqlite3Strlen30(zName);
/* First search for a match amongst the application-defined functions.
*/
- p = functionSearch(&db->aFunc, h, zName, nName);
+ p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -384,9 +385,9 @@ FuncDef *sqlite3FindFunction(
** So we must not search for built-ins when creating a new function.
*/
if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
bestScore = 0;
- p = functionSearch(pHash, h, zName, nName);
+ h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
+ p = functionSearch(h, zName);
while( p ){
int score = matchQuality(p, nArg, enc);
if( score>bestScore ){
@@ -403,12 +404,19 @@ FuncDef *sqlite3FindFunction(
*/
if( createFlag && bestScorezName = (char *)&pBest[1];
+ FuncDef *pOther;
+ pBest->zName = (const char*)&pBest[1];
pBest->nArg = (u16)nArg;
pBest->funcFlags = enc;
- memcpy(pBest->zName, zName, nName);
- pBest->zName[nName] = 0;
- sqlite3FuncDefInsert(&db->aFunc, pBest);
+ memcpy((char*)&pBest[1], zName, nName+1);
+ pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest);
+ if( pOther==pBest ){
+ sqlite3DbFree(db, pBest);
+ sqlite3OomFault(db);
+ return 0;
+ }else{
+ pBest->pNext = pOther;
+ }
}
if( pBest && (pBest->xSFunc || createFlag) ){
diff --git a/src/complete.c b/src/complete.c
index b120b7e811..bb2c03098e 100644
--- a/src/complete.c
+++ b/src/complete.c
@@ -281,7 +281,7 @@ int sqlite3_complete16(const void *zSql){
if( zSql8 ){
rc = sqlite3_complete(zSql8);
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3ValueFree(pVal);
return rc & 0xff;
diff --git a/src/date.c b/src/date.c
index 0a1d0e0798..ef05d44086 100644
--- a/src/date.c
+++ b/src/date.c
@@ -1136,7 +1136,7 @@ static void currentTimeFunc(
** external linkage.
*/
void sqlite3RegisterDateTimeFunctions(void){
- static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
+ static FuncDef aDateTimeFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS
DFUNCTION(julianday, -1, 0, 0, juliandayFunc ),
DFUNCTION(date, -1, 0, 0, dateFunc ),
@@ -1152,11 +1152,5 @@ void sqlite3RegisterDateTimeFunctions(void){
STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
#endif
};
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
-
- for(i=0; ibase.pVtab = pVTab;
@@ -349,7 +349,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
sqlite3BtreeLeave(pBt);
p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
- if( p->aCell==0 ) return SQLITE_NOMEM;
+ if( p->aCell==0 ) return SQLITE_NOMEM_BKPT;
memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
for(i=0; inCell; i++){
@@ -382,7 +382,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){
pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
pCell->nOvfl = nOvfl;
pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
- if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
+ if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
for(j=1; jaPage[0].iCell = 0;
pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
pCsr->iPage = 0;
- if( z==0 ) rc = SQLITE_NOMEM;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
}else{
pCsr->isEof = 1;
return sqlite3_reset(pCsr->pStmt);
@@ -496,7 +496,7 @@ statNextRestart:
}
pCell->iOvfl++;
statSizeAndOffset(pCsr);
- return z==0 ? SQLITE_NOMEM : SQLITE_OK;
+ return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
}
if( p->iRightChildPg ) break;
p->iCell++;
@@ -520,7 +520,7 @@ statNextRestart:
p[1].iCell = 0;
p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
p->iCell++;
- if( z==0 ) rc = SQLITE_NOMEM;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
}
@@ -554,7 +554,7 @@ statNextRestart:
pCsr->nUnused = p->nUnused;
pCsr->nMxPayload = p->nMxPayload;
pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
- if( z==0 ) rc = SQLITE_NOMEM;
+ if( z==0 ) rc = SQLITE_NOMEM_BKPT;
nPayload = 0;
for(i=0; inCell; i++){
nPayload += p->aCell[i].nLocal;
@@ -588,7 +588,7 @@ static int statFilter(
if( pCsr->iDb<0 ){
sqlite3_free(pCursor->pVtab->zErrMsg);
pCursor->pVtab->zErrMsg = sqlite3_mprintf("no such schema: %s", zDbase);
- return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM;
+ return pCursor->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM_BKPT;
}
}else{
pCsr->iDb = pTab->iDb;
@@ -604,7 +604,7 @@ static int statFilter(
" FROM \"%w\".%s WHERE rootpage!=0"
" ORDER BY name", pTab->db->aDb[pCsr->iDb].zName, zMaster);
if( zSql==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
diff --git a/src/expr.c b/src/expr.c
index 8d96ba10cd..3070de96fa 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -2888,7 +2888,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
ExprList *pFarg; /* List of function arguments */
int nFarg; /* Number of function arguments */
FuncDef *pDef; /* The function definition object */
- int nId; /* Length of the function name in bytes */
const char *zId; /* The function name */
u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
@@ -2904,10 +2903,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
nFarg = pFarg ? pFarg->nExpr : 0;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
zId = pExpr->u.zToken;
- nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0);
+ pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
if( pDef==0 || pDef->xFinalize!=0 ){
- sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId);
+ sqlite3ErrorMsg(pParse, "unknown function: %s()", zId);
break;
}
@@ -4132,7 +4130,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
pItem->iMem = ++pParse->nMem;
assert( !ExprHasProperty(pExpr, EP_IntValue) );
pItem->pFunc = sqlite3FindFunction(pParse->db,
- pExpr->u.zToken, sqlite3Strlen30(pExpr->u.zToken),
+ pExpr->u.zToken,
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
if( pExpr->flags & EP_Distinct ){
pItem->iDistinct = pParse->nTab++;
diff --git a/src/func.c b/src/func.c
index d615cf90b1..662a08f504 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1611,7 +1611,7 @@ static void groupConcatFinalize(sqlite3_context *context){
** of the built-in functions above are part of the global function set.
** This routine only deals with those that are not global.
*/
-void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
+void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
int rc = sqlite3_overload_function(db, "MATCH", 2);
assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
if( rc==SQLITE_NOMEM ){
@@ -1624,8 +1624,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
*/
static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){
FuncDef *pDef;
- pDef = sqlite3FindFunction(db, zName, sqlite3Strlen30(zName),
- 2, SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0);
if( ALWAYS(pDef) ){
pDef->funcFlags |= flagVal;
}
@@ -1673,9 +1672,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken,
- sqlite3Strlen30(pExpr->u.zToken),
- 2, SQLITE_UTF8, 0);
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
@@ -1699,7 +1696,7 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
**
** After this routine runs
*/
-void sqlite3RegisterGlobalFunctions(void){
+void sqlite3RegisterBuiltinFunctions(void){
/*
** The following array holds FuncDef structures for all of the functions
** defined in this file.
@@ -1707,8 +1704,27 @@ void sqlite3RegisterGlobalFunctions(void){
** The array cannot be constant since changes are made to the
** FuncDef.pHash elements at start-time. The elements of this array
** are read-only after initialization is complete.
+ **
+ ** For peak efficiency, put the most frequently used function last.
*/
- static SQLITE_WSD FuncDef aBuiltinFunc[] = {
+ static FuncDef aBuiltinFunc[] = {
+#ifdef SQLITE_SOUNDEX
+ FUNCTION(soundex, 1, 0, 0, soundexFunc ),
+#endif
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ VFUNCTION(load_extension, 1, 0, 0, loadExt ),
+ VFUNCTION(load_extension, 2, 0, 0, loadExt ),
+#endif
+#if SQLITE_USER_AUTHENTICATION
+ FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
+#endif
+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
+ DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
+#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
+ FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
+ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
@@ -1726,8 +1742,6 @@ void sqlite3RegisterGlobalFunctions(void){
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
FUNCTION(instr, 2, 0, 0, instrFunc ),
- FUNCTION(substr, 2, 0, 0, substrFunc ),
- FUNCTION(substr, 3, 0, 0, substrFunc ),
FUNCTION(printf, -1, 0, 0, printfFunc ),
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
FUNCTION(char, -1, 0, 0, charFunc ),
@@ -1738,40 +1752,22 @@ void sqlite3RegisterGlobalFunctions(void){
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
- FUNCTION(coalesce, 1, 0, 0, 0 ),
- FUNCTION(coalesce, 0, 0, 0, 0 ),
- FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
- FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
- FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
- FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
-#if SQLITE_USER_AUTHENTICATION
- FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ),
-#endif
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
- DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ),
- DFUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ),
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
FUNCTION(quote, 1, 0, 0, quoteFunc ),
VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid),
VFUNCTION(changes, 0, 0, 0, changes ),
VFUNCTION(total_changes, 0, 0, 0, total_changes ),
FUNCTION(replace, 3, 0, 0, replaceFunc ),
FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ),
- #ifdef SQLITE_SOUNDEX
- FUNCTION(soundex, 1, 0, 0, soundexFunc ),
- #endif
- #ifndef SQLITE_OMIT_LOAD_EXTENSION
- VFUNCTION(load_extension, 1, 0, 0, loadExt ),
- VFUNCTION(load_extension, 2, 0, 0, loadExt ),
- #endif
+ FUNCTION(substr, 2, 0, 0, substrFunc ),
+ FUNCTION(substr, 3, 0, 0, substrFunc ),
AGGREGATE(sum, 1, 0, 0, sumStep, sumFinalize ),
AGGREGATE(total, 1, 0, 0, sumStep, totalFinalize ),
AGGREGATE(avg, 1, 0, 0, sumStep, avgFinalize ),
@@ -1789,20 +1785,32 @@ void sqlite3RegisterGlobalFunctions(void){
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
+ FUNCTION(coalesce, 1, 0, 0, 0 ),
+ FUNCTION(coalesce, 0, 0, 0, 0 ),
+ FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
};
-
- int i;
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
- FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aBuiltinFunc);
-
- for(i=0; iu.pHash){
+ int n = sqlite3Strlen30(p->zName);
+ int h = p->zName[0] + n;
+ printf(" %s(%d)", p->zName, h);
+ }
+ printf("\n");
+ }
+ }
#endif
}
diff --git a/src/global.c b/src/global.c
index 64966b35d7..294d62fea8 100644
--- a/src/global.c
+++ b/src/global.c
@@ -219,7 +219,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = {
** database connections. After initialization, this table is
** read-only.
*/
-SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+FuncDefHash sqlite3BuiltinFunctions;
/*
** Constant tokens for values 0 and 1.
diff --git a/src/journal.c b/src/journal.c
index fed27be3e3..a5cf8c8e2f 100644
--- a/src/journal.c
+++ b/src/journal.c
@@ -212,7 +212,7 @@ int sqlite3JournalOpen(
if( nBuf>0 ){
p->zBuf = sqlite3MallocZero(nBuf);
if( !p->zBuf ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}else{
return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
diff --git a/src/legacy.c b/src/legacy.c
index 1b5e518d43..bd34512d31 100644
--- a/src/legacy.c
+++ b/src/legacy.c
@@ -131,7 +131,7 @@ exec_out:
if( *pzErrMsg ){
memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
sqlite3Error(db, SQLITE_NOMEM);
}
}else if( pzErrMsg ){
diff --git a/src/loadext.c b/src/loadext.c
index 94298c4763..3469fbb73d 100644
--- a/src/loadext.c
+++ b/src/loadext.c
@@ -478,7 +478,7 @@ static int sqlite3LoadExtension(
#if SQLITE_OS_UNIX || SQLITE_OS_WIN
for(ii=0; ii=0 && zFile[iFile]!='/'; iFile--){}
@@ -557,7 +557,7 @@ static int sqlite3LoadExtension(
/* Append the new shared library handle to the db->aExtension array. */
aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1));
if( aHandle==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( db->nExtension>0 ){
memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension);
@@ -679,7 +679,7 @@ int sqlite3_auto_extension(void (*xInit)(void)){
void (**aNew)(void);
aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
if( aNew==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
wsdAutoext.aExt = aNew;
wsdAutoext.aExt[wsdAutoext.nExt] = xInit;
diff --git a/src/main.c b/src/main.c
index 5def95d32e..9a8c156c6f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -187,7 +187,7 @@ int sqlite3_initialize(void){
sqlite3GlobalConfig.pInitMutex =
sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -218,7 +218,6 @@ int sqlite3_initialize(void){
*/
sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex);
if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
- FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
sqlite3GlobalConfig.inProgress = 1;
#ifdef SQLITE_ENABLE_SQLLOG
{
@@ -226,8 +225,8 @@ int sqlite3_initialize(void){
sqlite3_init_sqllog();
}
#endif
- memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
- sqlite3RegisterGlobalFunctions();
+ memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions));
+ sqlite3RegisterBuiltinFunctions();
if( sqlite3GlobalConfig.isPCacheInit==0 ){
rc = sqlite3PcacheInitialize();
}
@@ -958,7 +957,7 @@ void sqlite3CloseSavepoints(sqlite3 *db){
** with SQLITE_ANY as the encoding.
*/
static void functionDestroy(sqlite3 *db, FuncDef *p){
- FuncDestructor *pDestructor = p->pDestructor;
+ FuncDestructor *pDestructor = p->u.pDestructor;
if( pDestructor ){
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
@@ -1140,18 +1139,17 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
*/
sqlite3ConnectionClosed(db);
- for(j=0; jaFunc.a); j++){
- FuncDef *pNext, *pHash, *p;
- for(p=db->aFunc.a[j]; p; p=pHash){
- pHash = p->pHash;
- while( p ){
- functionDestroy(db, p);
- pNext = p->pNext;
- sqlite3DbFree(db, p);
- p = pNext;
- }
- }
+ for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
+ FuncDef *pNext, *p;
+ p = sqliteHashData(i);
+ do{
+ functionDestroy(db, p);
+ pNext = p->pNext;
+ sqlite3DbFree(db, p);
+ p = pNext;
+ }while( p );
}
+ sqlite3HashClear(&db->aFunc);
for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
CollSeq *pColl = (CollSeq *)sqliteHashData(i);
/* Invoke any destructors registered for collation sequence user data. */
@@ -1630,7 +1628,7 @@ int sqlite3CreateFunc(
** is being overridden/deleted but there are no active VMs, allow the
** operation to continue but invalidate all precompiled statements.
*/
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
+ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0);
if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
if( db->nVdbeActive ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY,
@@ -1642,10 +1640,10 @@ int sqlite3CreateFunc(
}
}
- p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 1);
+ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1);
assert(p || db->mallocFailed);
if( !p ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* If an older version of the function with a configured destructor is
@@ -1655,7 +1653,7 @@ int sqlite3CreateFunc(
if( pDestructor ){
pDestructor->nRef++;
}
- p->pDestructor = pDestructor;
+ p->u.pDestructor = pDestructor;
p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
testcase( p->funcFlags & SQLITE_DETERMINISTIC );
p->xSFunc = xSFunc ? xSFunc : xStep;
@@ -1770,7 +1768,6 @@ int sqlite3_overload_function(
const char *zName,
int nArg
){
- int nName = sqlite3Strlen30(zName);
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
@@ -1779,7 +1776,7 @@ int sqlite3_overload_function(
}
#endif
sqlite3_mutex_enter(db->mutex);
- if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
+ if( sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)==0 ){
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
0, sqlite3InvalidFunction, 0, 0, 0);
}
@@ -2170,14 +2167,14 @@ int sqlite3TempInMemory(const sqlite3 *db){
const char *sqlite3_errmsg(sqlite3 *db){
const char *z;
if( !db ){
- return sqlite3ErrStr(SQLITE_NOMEM);
+ return sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return sqlite3ErrStr(SQLITE_MISUSE_BKPT);
}
sqlite3_mutex_enter(db->mutex);
if( db->mallocFailed ){
- z = sqlite3ErrStr(SQLITE_NOMEM);
+ z = sqlite3ErrStr(SQLITE_NOMEM_BKPT);
}else{
testcase( db->pErr==0 );
z = (char*)sqlite3_value_text(db->pErr);
@@ -2245,7 +2242,7 @@ int sqlite3_errcode(sqlite3 *db){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return db->errCode & db->errMask;
}
@@ -2254,7 +2251,7 @@ int sqlite3_extended_errcode(sqlite3 *db){
return SQLITE_MISUSE_BKPT;
}
if( !db || db->mallocFailed ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return db->errCode;
}
@@ -2334,7 +2331,7 @@ static int createCollation(
}
pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1);
- if( pColl==0 ) return SQLITE_NOMEM;
+ if( pColl==0 ) return SQLITE_NOMEM_BKPT;
pColl->xCmp = xCompare;
pColl->pUser = pCtx;
pColl->xDel = xDel;
@@ -2382,8 +2379,8 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_VDBE_OP<40
# error SQLITE_MAX_VDBE_OP must be at least 40
#endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
+#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
+# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
#endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125
# error SQLITE_MAX_ATTACHED must be between 0 and 125
@@ -2513,7 +2510,7 @@ int sqlite3ParseUri(
for(iIn=0; iInaDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
- /* The default safety_level for the main database is 'full'; for the temp
- ** database it is 'NONE'. This matches the pager layer defaults.
+ /* The default safety_level for the main database is FULL; for the temp
+ ** database it is OFF. This matches the pager layer defaults.
*/
db->aDb[0].zName = "main";
- db->aDb[0].safety_level = 3;
+ db->aDb[0].safety_level = PAGER_SYNCHRONOUS_FULL;
db->aDb[1].zName = "temp";
- db->aDb[1].safety_level = 1;
+ db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
db->magic = SQLITE_MAGIC_OPEN;
if( db->mallocFailed ){
@@ -2907,7 +2904,7 @@ static int openDatabase(
** is accessed.
*/
sqlite3Error(db, SQLITE_OK);
- sqlite3RegisterBuiltinFunctions(db);
+ sqlite3RegisterPerConnectionBuiltinFunctions(db);
/* Load automatic extensions - extensions that have been registered
** using the sqlite3_automatic_extension() API.
@@ -3081,7 +3078,7 @@ int sqlite3_open16(
SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
}
}else{
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
sqlite3ValueFree(pVal);
@@ -3226,7 +3223,7 @@ int sqlite3_get_autocommit(sqlite3 *db){
/*
** The following routines are substitutes for constants SQLITE_CORRUPT,
-** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error
+** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_NOMEM and possibly other error
** constants. They serve two purposes:
**
** 1. Serve as a convenient place to set a breakpoint in a debugger
@@ -3235,28 +3232,33 @@ int sqlite3_get_autocommit(sqlite3 *db){
** 2. Invoke sqlite3_log() to provide the source code location where
** a low-level error is first detected.
*/
+static int reportError(int iErr, int lineno, const char *zType){
+ sqlite3_log(iErr, "%s at line %d of [%.10s]",
+ zType, lineno, 20+sqlite3_sourceid());
+ return iErr;
+}
int sqlite3CorruptError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_CORRUPT,
- "database corruption at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_CORRUPT;
+ return reportError(SQLITE_CORRUPT, lineno, "database corruption");
}
int sqlite3MisuseError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_MISUSE,
- "misuse at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_MISUSE;
+ return reportError(SQLITE_MISUSE, lineno, "misuse");
}
int sqlite3CantopenError(int lineno){
testcase( sqlite3GlobalConfig.xLog!=0 );
- sqlite3_log(SQLITE_CANTOPEN,
- "cannot open file at line %d of [%.10s]",
- lineno, 20+sqlite3_sourceid());
- return SQLITE_CANTOPEN;
+ return reportError(SQLITE_CANTOPEN, lineno, "cannot open file");
}
-
+#ifdef SQLITE_DEBUG
+int sqlite3NomemError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return reportError(SQLITE_NOMEM, lineno, "OOM");
+}
+int sqlite3IoerrnomemError(int lineno){
+ testcase( sqlite3GlobalConfig.xLog!=0 );
+ return reportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error");
+}
+#endif
#ifndef SQLITE_OMIT_DEPRECATED
/*
diff --git a/src/malloc.c b/src/malloc.c
index ebe0440350..462d78e68c 100644
--- a/src/malloc.c
+++ b/src/malloc.c
@@ -795,7 +795,7 @@ void sqlite3OomClear(sqlite3 *db){
static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
sqlite3OomClear(db);
sqlite3Error(db, SQLITE_NOMEM);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/*
diff --git a/src/memjournal.c b/src/memjournal.c
index 6452cecc37..62594530e0 100644
--- a/src/memjournal.c
+++ b/src/memjournal.c
@@ -133,7 +133,7 @@ static int memjrnlWrite(
/* New chunk is required to extend the file. */
FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
if( !pNew ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
pNew->pNext = 0;
if( pChunk ){
diff --git a/src/os.c b/src/os.c
index 90130d0eb7..2fd44abf85 100644
--- a/src/os.c
+++ b/src/os.c
@@ -68,7 +68,7 @@ int sqlite3_memdebug_vfs_oom_test = 1;
#define DO_OS_MALLOC_TEST(x) \
if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \
void *pTstAlloc = sqlite3Malloc(10); \
- if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \
+ if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \
sqlite3_free(pTstAlloc); \
}
#else
@@ -287,7 +287,7 @@ int sqlite3OsOpenMalloc(
int flags,
int *pOutFlags
){
- int rc = SQLITE_NOMEM;
+ int rc;
sqlite3_file *pFile;
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
if( pFile ){
@@ -297,6 +297,8 @@ int sqlite3OsOpenMalloc(
}else{
*ppFile = pFile;
}
+ }else{
+ rc = SQLITE_NOMEM_BKPT;
}
return rc;
}
@@ -316,7 +318,7 @@ int sqlite3OsCloseFree(sqlite3_file *pFile){
*/
int sqlite3OsInit(void){
void *p = sqlite3_malloc(10);
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
sqlite3_free(p);
return sqlite3_os_init();
}
diff --git a/src/os_unix.c b/src/os_unix.c
index fe1fc6af19..ea07bd99f3 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -1302,7 +1302,7 @@ static int findInodeInfo(
if( pInode==0 ){
pInode = sqlite3_malloc64( sizeof(*pInode) );
if( pInode==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(pInode, 0, sizeof(*pInode));
memcpy(&pInode->fileId, &fileId, sizeof(fileId));
@@ -4222,7 +4222,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
/* Allocate space for the new unixShm object. */
p = sqlite3_malloc64( sizeof(*p) );
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
memset(p, 0, sizeof(*p));
assert( pDbFd->pShm==0 );
@@ -4254,7 +4254,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
#endif
pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
if( pShmNode==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename);
@@ -4272,7 +4272,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
pShmNode->pInode = pDbFd->pInode;
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto shm_open_err;
}
@@ -4445,7 +4445,7 @@ static int unixShmMap(
pShmNode->apRegion, nReqRegion*sizeof(char *)
);
if( !apNew ){
- rc = SQLITE_IOERR_NOMEM;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shmpage_out;
}
pShmNode->apRegion = apNew;
@@ -4465,7 +4465,7 @@ static int unixShmMap(
}else{
pMem = sqlite3_malloc64(szRegion);
if( pMem==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto shmpage_out;
}
memset(pMem, 0, szRegion);
@@ -5243,7 +5243,7 @@ static int fillInUnixFile(
pNew->pId = vxworksFindFileId(zFilename);
if( pNew->pId==0 ){
ctrlFlags |= UNIXFILE_NOLOCK;
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
#endif
@@ -5299,7 +5299,7 @@ static int fillInUnixFile(
afpLockingContext *pCtx;
pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
/* NB: zFilename exists and remains valid until the file is closed
** according to requirement F11141. So we do not need to make a
@@ -5329,7 +5329,7 @@ static int fillInUnixFile(
nFilename = (int)strlen(zFilename) + 6;
zLockFile = (char *)sqlite3_malloc64(nFilename);
if( zLockFile==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
@@ -5352,7 +5352,7 @@ static int fillInUnixFile(
if( zSemName[n]=='/' ) zSemName[n] = '_';
pNew->pInode->pSem = sem_open(zSemName, O_CREAT, 0666, 1);
if( pNew->pInode->pSem == SEM_FAILED ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
pNew->pInode->aSemName[0] = '\0';
}
}
@@ -5693,7 +5693,7 @@ static int unixOpen(
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
p->pUnused = pUnused;
@@ -5779,7 +5779,7 @@ static int unixOpen(
zPath = sqlite3_mprintf("%s", zName);
if( zPath==0 ){
robust_close(p, fd, __LINE__);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
#else
osUnlink(zName);
@@ -6011,7 +6011,7 @@ static int unixFullPathname(
if( bLink ){
if( zDel==0 ){
zDel = sqlite3_malloc(nOut);
- if( zDel==0 ) rc = SQLITE_NOMEM;
+ if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
}else if( ++nLink>SQLITE_MAX_SYMLINKS ){
rc = SQLITE_CANTOPEN_BKPT;
}
@@ -6555,7 +6555,7 @@ static int proxyCreateUnixFile(
}else{
pUnused = sqlite3_malloc64(sizeof(*pUnused));
if( !pUnused ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
if( fd<0 ){
@@ -6588,7 +6588,7 @@ static int proxyCreateUnixFile(
pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
if( pNew==NULL ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto end_create_proxy;
}
memset(pNew, 0, sizeof(unixFile));
@@ -7001,7 +7001,7 @@ static int proxyTakeConch(unixFile *pFile){
if( tempLockPath ){
pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath);
if( !pCtx->lockProxyPath ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
}
@@ -7066,7 +7066,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
** the name of the original database file. */
*pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
if( conchPath==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(conchPath, dbPath, len+1);
@@ -7182,7 +7182,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
pCtx = sqlite3_malloc64( sizeof(*pCtx) );
if( pCtx==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(pCtx, 0, sizeof(*pCtx));
@@ -7218,7 +7218,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
if( rc==SQLITE_OK ){
pCtx->dbPath = sqlite3DbStrDup(0, dbPath);
if( pCtx->dbPath==NULL ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
}
if( rc==SQLITE_OK ){
diff --git a/src/os_win.c b/src/os_win.c
index eda6cf59fb..af6b1c814c 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -1222,7 +1222,7 @@ int sqlite3_win32_compact_heap(LPUINT pnLargest){
if( lastErrno==NO_ERROR ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
(void*)hHeap);
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
osGetLastError(), (void*)hHeap);
@@ -1542,7 +1542,7 @@ static int winMemInit(void *pAppData){
"failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
dwMaximumSize);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pWinMemData->bOwned = TRUE;
assert( pWinMemData->bOwned );
@@ -1552,7 +1552,7 @@ static int winMemInit(void *pAppData){
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to GetProcessHeap (%lu)", osGetLastError());
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pWinMemData->bOwned = FALSE;
assert( !pWinMemData->bOwned );
@@ -1789,7 +1789,7 @@ int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
if( zValue && zValue[0] ){
zValueUtf8 = winUnicodeToUtf8(zValue);
if ( zValueUtf8==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
sqlite3_free(*ppDirectory);
@@ -2066,7 +2066,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){
zName = winUtf8ToUnicode(zFilename);
if( zName==0 ){
/* out of memory */
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
/* Initialize the local lockdata */
@@ -3615,12 +3615,12 @@ static int winOpenSharedMemory(winFile *pDbFd){
** allocate space for a new winShmNode and filename.
*/
p = sqlite3MallocZero( sizeof(*p) );
- if( p==0 ) return SQLITE_IOERR_NOMEM;
+ if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
nName = sqlite3Strlen30(pDbFd->zPath);
pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
if( pNew==0 ){
sqlite3_free(p);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
@@ -3647,7 +3647,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
if( pShmNode->mutex==0 ){
- rc = SQLITE_IOERR_NOMEM;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shm_open_err;
}
@@ -3952,7 +3952,7 @@ static int winShmMap(
pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
);
if( !apNew ){
- rc = SQLITE_IOERR_NOMEM;
+ rc = SQLITE_IOERR_NOMEM_BKPT;
goto shmpage_out;
}
pShmNode->aRegion = apNew;
@@ -4382,7 +4382,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
zBuf = sqlite3MallocZero( nBuf );
if( !zBuf ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
/* Figure out the effective temporary directory. First, check if one
@@ -4440,7 +4440,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( winIsDir(zConverted) ){
sqlite3_snprintf(nMax, zBuf, "%s", zDir);
@@ -4453,7 +4453,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
@@ -4474,7 +4474,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
sqlite3_free(zConverted);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -4492,7 +4492,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zWidePath ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osGetTempPathW(nMax, zWidePath)==0 ){
sqlite3_free(zWidePath);
@@ -4510,7 +4510,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
sqlite3_free(zWidePath);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
@@ -4520,7 +4520,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
if( !zMbcsPath ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osGetTempPathA(nMax, zMbcsPath)==0 ){
sqlite3_free(zBuf);
@@ -4535,7 +4535,7 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
}else{
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
}
#endif /* SQLITE_WIN32_HAS_ANSI */
@@ -4727,7 +4727,7 @@ static int winOpen(
if( zConverted==0 ){
sqlite3_free(zTmpname);
OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( winIsDir(zConverted) ){
@@ -4927,7 +4927,7 @@ static int winDelete(
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
do {
@@ -5035,7 +5035,7 @@ static int winAccess(
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
int cnt = 0;
@@ -5162,7 +5162,7 @@ static int winFullPathname(
*/
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
@@ -5174,7 +5174,7 @@ static int winFullPathname(
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
sqlite3_data_directory, winGetDirSep(), zUtf8);
@@ -5184,7 +5184,7 @@ static int winFullPathname(
}else{
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
@@ -5196,7 +5196,7 @@ static int winFullPathname(
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
sqlite3_free(zUtf8);
@@ -5256,7 +5256,7 @@ static int winFullPathname(
}
zConverted = winConvertFromUtf8Filename(zRelative);
if( zConverted==0 ){
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
LPWSTR zTemp;
@@ -5270,7 +5270,7 @@ static int winFullPathname(
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
@@ -5296,7 +5296,7 @@ static int winFullPathname(
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
if( nByte==0 ){
@@ -5315,7 +5315,7 @@ static int winFullPathname(
sqlite3_free(zOut);
return SQLITE_OK;
}else{
- return SQLITE_IOERR_NOMEM;
+ return SQLITE_IOERR_NOMEM_BKPT;
}
#endif
}
@@ -5390,65 +5390,85 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
#define winDlClose 0
#endif
+/* State information for the randomness gatherer. */
+typedef struct EntropyGatherer EntropyGatherer;
+struct EntropyGatherer {
+ unsigned char *a; /* Gather entropy into this buffer */
+ int na; /* Size of a[] in bytes */
+ int i; /* XOR next input into a[i] */
+ int nXor; /* Number of XOR operations done */
+};
+
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
+/* Mix sz bytes of entropy into p. */
+static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
+ int j, k;
+ for(j=0, k=p->i; ja[k++] ^= x[j];
+ if( k>=p->na ) k = 0;
+ }
+ p->i = k;
+ p->nXor += sz;
+}
+#endif /* !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) */
/*
** Write up to nBuf bytes of randomness into zBuf.
*/
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
- int n = 0;
- UNUSED_PARAMETER(pVfs);
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
- n = nBuf;
+ UNUSED_PARAMETER(pVfs);
memset(zBuf, 0, nBuf);
+ return nBuf;
#else
- if( sizeof(SYSTEMTIME)<=nBuf-n ){
+ EntropyGatherer e;
+ UNUSED_PARAMETER(pVfs);
+ memset(zBuf, 0, nBuf);
+#if defined(_MSC_VER) && _MSC_VER>=1400
+ rand_s((int*)zBuf); /* rand_s() is not available with MinGW */
+#endif /* defined(_MSC_VER) && _MSC_VER>=1400 */
+ e.a = (unsigned char*)zBuf;
+ e.na = nBuf;
+ e.nXor = 0;
+ e.i = 0;
+ {
SYSTEMTIME x;
osGetSystemTime(&x);
- memcpy(&zBuf[n], &x, sizeof(x));
- n += sizeof(x);
+ xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
}
- if( sizeof(DWORD)<=nBuf-n ){
+ {
DWORD pid = osGetCurrentProcessId();
- memcpy(&zBuf[n], &pid, sizeof(pid));
- n += sizeof(pid);
+ xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
}
#if SQLITE_OS_WINRT
- if( sizeof(ULONGLONG)<=nBuf-n ){
+ {
ULONGLONG cnt = osGetTickCount64();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(ULONGLONG));
}
#else
- if( sizeof(DWORD)<=nBuf-n ){
+ {
DWORD cnt = osGetTickCount();
- memcpy(&zBuf[n], &cnt, sizeof(cnt));
- n += sizeof(cnt);
+ xorMemory(&e, (unsigned char*)&cnt, sizeof(DWORD));
}
-#endif
- if( sizeof(LARGE_INTEGER)<=nBuf-n ){
+#endif /* SQLITE_OS_WINRT */
+ {
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
- memcpy(&zBuf[n], &i, sizeof(i));
- n += sizeof(i);
+ xorMemory(&e, (unsigned char*)&i, sizeof(LARGE_INTEGER));
}
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
- if( sizeof(UUID)<=nBuf-n ){
+ {
UUID id;
memset(&id, 0, sizeof(UUID));
osUuidCreate(&id);
- memcpy(&zBuf[n], &id, sizeof(UUID));
- n += sizeof(UUID);
- }
- if( sizeof(UUID)<=nBuf-n ){
- UUID id;
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
memset(&id, 0, sizeof(UUID));
osUuidCreateSequential(&id);
- memcpy(&zBuf[n], &id, sizeof(UUID));
- n += sizeof(UUID);
+ xorMemory(&e, (unsigned char*)&id, sizeof(UUID));
}
-#endif
-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
- return n;
+#endif /* !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID */
+ return e.nXor>nBuf ? nBuf : e.nXor;
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) */
}
diff --git a/src/pager.c b/src/pager.c
index 5c61968e36..51bd45e486 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -2324,9 +2324,9 @@ static int pager_playback_one_page(
pPager->dbFileSize = pgno;
}
if( pPager->pBackup ){
- CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
+ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT);
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
- CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
+ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData);
}
}else if( !isMainJrnl && pPg==0 ){
/* If this is a rollback of a savepoint and data was not written to
@@ -2398,7 +2398,7 @@ static int pager_playback_one_page(
}
/* Decode the page just read from disk */
- CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
+ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT);
sqlite3PcacheRelease(pPg);
}
return rc;
@@ -2464,7 +2464,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
if( !pMaster ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
@@ -2481,7 +2481,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
nMasterPtr = pVfs->mxPathname+1;
zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
if( !zMasterJournal ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto delmaster_out;
}
zMasterPtr = &zMasterJournal[nMasterJournal+1];
@@ -2951,7 +2951,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
}
}
- CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
+ CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM_BKPT);
PAGER_INCR(sqlite3_pager_readdb_count);
PAGER_INCR(pPager->nRead);
@@ -3311,7 +3311,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
if( pSavepoint ){
pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
if( !pDone ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
}
@@ -3674,7 +3674,7 @@ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
}
if( rc==SQLITE_OK ){
pNew = (char *)sqlite3PageMalloc(pageSize);
- if( !pNew ) rc = SQLITE_NOMEM;
+ if( !pNew ) rc = SQLITE_NOMEM_BKPT;
}
if( rc==SQLITE_OK ){
@@ -3950,7 +3950,7 @@ static int pagerAcquireMapPage(
*ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
if( p==0 ){
sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
p->pExtra = (void *)&p[1];
p->flags = PGHDR_MMAP;
@@ -4308,7 +4308,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
if( pList->pgno==1 ) pager_write_changecounter(pList);
/* Encode the database */
- CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
+ CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData);
/* Write out the page data. */
rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
@@ -4395,7 +4395,7 @@ static int subjournalPage(PgHdr *pPg){
i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
char *pData2;
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+ CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
rc = write32bits(pPager->sjfd, offset, pPg->pgno);
if( rc==SQLITE_OK ){
@@ -4599,7 +4599,7 @@ int sqlite3PagerOpen(
memDb = 1;
if( zFilename && zFilename[0] ){
zPathname = sqlite3DbStrDup(0, zFilename);
- if( zPathname==0 ) return SQLITE_NOMEM;
+ if( zPathname==0 ) return SQLITE_NOMEM_BKPT;
nPathname = sqlite3Strlen30(zPathname);
zFilename = 0;
}
@@ -4615,7 +4615,7 @@ int sqlite3PagerOpen(
nPathname = pVfs->mxPathname+1;
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
if( zPathname==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
@@ -4668,7 +4668,7 @@ int sqlite3PagerOpen(
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pPager = (Pager*)(pPtr);
pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
@@ -5388,7 +5388,7 @@ int sqlite3PagerGet(
if( rc!=SQLITE_OK ) goto pager_acquire_err;
if( pBase==0 ){
pPg = *ppPage = 0;
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto pager_acquire_err;
}
}
@@ -5562,7 +5562,7 @@ static int pager_open_journal(Pager *pPager){
if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
if( pPager->pInJournal==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* Open the journal file if it is not already open. */
@@ -5717,7 +5717,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
assert( pPager->journalHdr<=pPager->journalOff );
- CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+ CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM_BKPT, pData2);
cksum = pager_cksum(pPager, (u8*)pData2);
/* Even if an IO or diskfull error occurs while journalling the
@@ -6074,7 +6074,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
if( DIRECT_MODE ){
const void *zBuf;
assert( pPager->dbFileSize>0 );
- CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
+ CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf);
if( rc==SQLITE_OK ){
rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
pPager->aStat[PAGER_STAT_WRITE]++;
@@ -6573,7 +6573,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
);
if( !aNew ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
pPager->aSavepoint = aNew;
@@ -6589,7 +6589,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){
aNew[ii].iSubRec = pPager->nSubRec;
aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
if( !aNew[ii].pInSavepoint ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( pagerUseWal(pPager) ){
sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
@@ -6738,14 +6738,6 @@ const char *sqlite3PagerJournalname(Pager *pPager){
return pPager->zJournal;
}
-/*
-** Return true if fsync() calls are disabled for this pager. Return FALSE
-** if fsync()s are executed normally.
-*/
-int sqlite3PagerNosync(Pager *pPager){
- return pPager->noSync;
-}
-
#ifdef SQLITE_HAS_CODEC
/*
** Set or retrieve the codec for this pager
diff --git a/src/pager.h b/src/pager.h
index 8d9f08108d..38a4982150 100644
--- a/src/pager.h
+++ b/src/pager.h
@@ -191,7 +191,6 @@ sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*);
sqlite3_file *sqlite3PagerJrnlFile(Pager*);
const char *sqlite3PagerJournalname(Pager*);
-int sqlite3PagerNosync(Pager*);
void *sqlite3PagerTempSpace(Pager*);
int sqlite3PagerIsMemdb(Pager*);
void sqlite3PagerCacheStat(Pager *, int, int, int *);
diff --git a/src/parse.y b/src/parse.y
index 0bfe4e473a..e7e0d1d953 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -35,7 +35,6 @@
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
}
%stack_overflow {
- UNUSED_PARAMETER(yypMinor); /* Silence some compiler warnings */
sqlite3ErrorMsg(pParse, "parser stack overflow");
}
@@ -139,9 +138,9 @@ trans_opt ::= TRANSACTION.
trans_opt ::= TRANSACTION nm.
%type transtype {int}
transtype(A) ::= . {A = TK_DEFERRED;}
-transtype(A) ::= DEFERRED(X). {A = @X;}
-transtype(A) ::= IMMEDIATE(X). {A = @X;}
-transtype(A) ::= EXCLUSIVE(X). {A = @X;}
+transtype(A) ::= DEFERRED(X). {A = @X; /*A-overwrites-X*/}
+transtype(A) ::= IMMEDIATE(X). {A = @X; /*A-overwrites-X*/}
+transtype(A) ::= EXCLUSIVE(X). {A = @X; /*A-overwrites-X*/}
cmd ::= COMMIT trans_opt. {sqlite3CommitTransaction(pParse);}
cmd ::= END trans_opt. {sqlite3CommitTransaction(pParse);}
cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);}
@@ -164,10 +163,8 @@ cmd ::= create_table create_table_args.
create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). {
sqlite3StartTable(pParse,&Y,&Z,T,0,0,E);
}
-createkw(A) ::= CREATE(X). {
- disableLookaside(pParse);
- A = X;
-}
+createkw(A) ::= CREATE(A). {disableLookaside(pParse);}
+
%type ifnotexists {int}
ifnotexists(A) ::= . {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
@@ -201,13 +198,11 @@ columnlist ::= column.
// datatype, and other keywords such as PRIMARY KEY, UNIQUE, REFERENCES,
// NOT NULL and so forth.
//
-column(A) ::= columnid(X) type carglist. {
- A.z = X.z;
- A.n = (int)(pParse->sLastToken.z-X.z) + pParse->sLastToken.n;
+column(A) ::= columnid(A) type carglist. {
+ A.n = (int)(pParse->sLastToken.z-A.z) + pParse->sLastToken.n;
}
-columnid(A) ::= nm(X). {
- sqlite3AddColumn(pParse,&X);
- A = X;
+columnid(A) ::= nm(A). {
+ sqlite3AddColumn(pParse,&A);
pParse->constraintName.n = 0;
}
@@ -265,9 +260,9 @@ columnid(A) ::= nm(X). {
// The name of a column or table can be any of the following:
//
%type nm {Token}
-nm(A) ::= id(X). {A = X;}
-nm(A) ::= STRING(X). {A = X;}
-nm(A) ::= JOIN_KW(X). {A = X;}
+nm(A) ::= id(A).
+nm(A) ::= STRING(A).
+nm(A) ::= JOIN_KW(A).
// A typetoken is really one or more tokens that form a type name such
// as can be found after the column name in a CREATE TABLE statement.
@@ -276,18 +271,16 @@ nm(A) ::= JOIN_KW(X). {A = X;}
%type typetoken {Token}
type ::= .
type ::= typetoken(X). {sqlite3AddColumnType(pParse,&X);}
-typetoken(A) ::= typename(X). {A = X;}
-typetoken(A) ::= typename(X) LP signed RP(Y). {
- A.z = X.z;
- A.n = (int)(&Y.z[Y.n] - X.z);
+typetoken(A) ::= typename(A).
+typetoken(A) ::= typename(A) LP signed RP(Y). {
+ A.n = (int)(&Y.z[Y.n] - A.z);
}
-typetoken(A) ::= typename(X) LP signed COMMA signed RP(Y). {
- A.z = X.z;
- A.n = (int)(&Y.z[Y.n] - X.z);
+typetoken(A) ::= typename(A) LP signed COMMA signed RP(Y). {
+ A.n = (int)(&Y.z[Y.n] - A.z);
}
%type typename {Token}
-typename(A) ::= ids(X). {A = X;}
-typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(int)(Y.z-X.z);}
+typename(A) ::= ids(A).
+typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);}
signed ::= plus_num.
signed ::= minus_num.
@@ -309,7 +302,7 @@ ccons ::= DEFAULT MINUS(A) term(X). {
}
ccons ::= DEFAULT id(X). {
ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, &X);
+ spanExpr(&v, pParse, TK_STRING, X);
sqlite3AddDefaultValue(pParse,&v);
}
@@ -339,7 +332,7 @@ autoinc(X) ::= AUTOINCR. {X = 1;}
//
%type refargs {int}
refargs(A) ::= . { A = OE_None*0x0101; /* EV: R-19803-45884 */}
-refargs(A) ::= refargs(X) refarg(Y). { A = (X & ~Y.mask) | Y.value; }
+refargs(A) ::= refargs(A) refarg(Y). { A = (A & ~Y.mask) | Y.value; }
%type refarg {struct {int value; int mask;}}
refarg(A) ::= MATCH nm. { A.value = 0; A.mask = 0x000000; }
refarg(A) ::= ON INSERT refact. { A.value = 0; A.mask = 0x000000; }
@@ -360,7 +353,7 @@ init_deferred_pred_opt(A) ::= INITIALLY DEFERRED. {A = 1;}
init_deferred_pred_opt(A) ::= INITIALLY IMMEDIATE. {A = 0;}
conslist_opt(A) ::= . {A.n = 0; A.z = 0;}
-conslist_opt(A) ::= COMMA(X) conslist. {A = X;}
+conslist_opt(A) ::= COMMA(A) conslist.
conslist ::= conslist tconscomma tcons.
conslist ::= tcons.
tconscomma ::= COMMA. {pParse->constraintName.n = 0;}
@@ -379,7 +372,7 @@ tcons ::= FOREIGN KEY LP eidlist(FA) RP
}
%type defer_subclause_opt {int}
defer_subclause_opt(A) ::= . {A = 0;}
-defer_subclause_opt(A) ::= defer_subclause(X). {A = X;}
+defer_subclause_opt(A) ::= defer_subclause(A).
// The following is a non-standard extension that allows us to declare the
// default behavior when there is a constraint conflict.
@@ -391,7 +384,7 @@ onconf(A) ::= . {A = OE_Default;}
onconf(A) ::= ON CONFLICT resolvetype(X). {A = X;}
orconf(A) ::= . {A = OE_Default;}
orconf(A) ::= OR resolvetype(X). {A = X;}
-resolvetype(A) ::= raisetype(X). {A = X;}
+resolvetype(A) ::= raisetype(A).
resolvetype(A) ::= IGNORE. {A = OE_Ignore;}
resolvetype(A) ::= REPLACE. {A = OE_Replace;}
@@ -463,14 +456,14 @@ select(A) ::= with(W) selectnowith(X). {
}else{
sqlite3WithDelete(pParse->db, W);
}
- A = p;
+ A = p; /*A-overwrites-W*/
}
-selectnowith(A) ::= oneselect(X). {A = X;}
+selectnowith(A) ::= oneselect(A).
%ifndef SQLITE_OMIT_COMPOUND_SELECT
-selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
+selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). {
Select *pRhs = Z;
- Select *pLhs = X;
+ Select *pLhs = A;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
@@ -491,12 +484,15 @@ selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
A = pRhs;
}
%type multiselect_op {int}
-multiselect_op(A) ::= UNION(OP). {A = @OP;}
+multiselect_op(A) ::= UNION(OP). {A = @OP; /*A-overwrites-OP*/}
multiselect_op(A) ::= UNION ALL. {A = TK_ALL;}
-multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP;}
+multiselect_op(A) ::= EXCEPT|INTERSECT(OP). {A = @OP; /*A-overwrites-OP*/}
%endif SQLITE_OMIT_COMPOUND_SELECT
oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
+#if SELECTTRACE_ENABLED
+ Token s = S; /*A-overwrites-S*/
+#endif
A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset);
#if SELECTTRACE_ENABLED
/* Populate the Select.zSelName[] string that is used to help with
@@ -509,7 +505,7 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
** is an integer that is incremented with each SELECT statement seen.
*/
if( A!=0 ){
- const char *z = S.z+6;
+ const char *z = s.z+6;
int i;
sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "#%d",
++pParse->nSelect);
@@ -523,20 +519,19 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
}
#endif /* SELECTRACE_ENABLED */
}
-oneselect(A) ::= values(X). {A = X;}
+oneselect(A) ::= values(A).
%type values {Select*}
%destructor values {sqlite3SelectDelete(pParse->db, $$);}
values(A) ::= VALUES LP nexprlist(X) RP. {
A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
}
-values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
- Select *pRight, *pLeft = X;
+values(A) ::= values(A) COMMA LP exprlist(Y) RP. {
+ Select *pRight, *pLeft = A;
pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
if( pRight ){
pRight->op = TK_ALL;
- pLeft = X;
pRight->pPrior = pLeft;
A = pRight;
}else{
@@ -561,22 +556,22 @@ distinct(A) ::= . {A = 0;}
%destructor selcollist {sqlite3ExprListDelete(pParse->db, $$);}
%type sclp {ExprList*}
%destructor sclp {sqlite3ExprListDelete(pParse->db, $$);}
-sclp(A) ::= selcollist(X) COMMA. {A = X;}
+sclp(A) ::= selcollist(A) COMMA.
sclp(A) ::= . {A = 0;}
-selcollist(A) ::= sclp(P) expr(X) as(Y). {
- A = sqlite3ExprListAppend(pParse, P, X.pExpr);
+selcollist(A) ::= sclp(A) expr(X) as(Y). {
+ A = sqlite3ExprListAppend(pParse, A, X.pExpr);
if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
sqlite3ExprListSetSpan(pParse,A,&X);
}
-selcollist(A) ::= sclp(P) STAR. {
+selcollist(A) ::= sclp(A) STAR. {
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
- A = sqlite3ExprListAppend(pParse, P, p);
+ A = sqlite3ExprListAppend(pParse, A, p);
}
-selcollist(A) ::= sclp(P) nm(X) DOT STAR(Y). {
+selcollist(A) ::= sclp(A) nm(X) DOT STAR(Y). {
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0, &Y);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- A = sqlite3ExprListAppend(pParse,P, pDot);
+ A = sqlite3ExprListAppend(pParse,A, pDot);
}
// An option "AS " phrase that can follow one of the expressions that
@@ -584,7 +579,7 @@ selcollist(A) ::= sclp(P) nm(X) DOT STAR(Y). {
//
%type as {Token}
as(X) ::= AS nm(Y). {X = Y;}
-as(X) ::= ids(Y). {X = Y;}
+as(X) ::= ids(X).
as(X) ::= . {X.n = 0;}
@@ -606,32 +601,31 @@ from(A) ::= FROM seltablist(X). {
// "seltablist" is a "Select Table List" - the content of the FROM clause
// in a SELECT statement. "stl_prefix" is a prefix of this list.
//
-stl_prefix(A) ::= seltablist(X) joinop(Y). {
- A = X;
+stl_prefix(A) ::= seltablist(A) joinop(Y). {
if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].fg.jointype = (u8)Y;
}
stl_prefix(A) ::= . {A = 0;}
-seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) as(Z) indexed_opt(I)
+seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_opt(I)
on_opt(N) using_opt(U). {
- A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U);
sqlite3SrcListIndexedBy(pParse, A, &I);
}
-seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
+seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
on_opt(N) using_opt(U). {
- A = sqlite3SrcListAppendFromTerm(pParse,X,&Y,&D,&Z,0,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U);
sqlite3SrcListFuncArgs(pParse, A, E);
}
%ifndef SQLITE_OMIT_SUBQUERY
- seltablist(A) ::= stl_prefix(X) LP select(S) RP
+ seltablist(A) ::= stl_prefix(A) LP select(S) RP
as(Z) on_opt(N) using_opt(U). {
- A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,S,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,N,U);
}
- seltablist(A) ::= stl_prefix(X) LP seltablist(F) RP
+ seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP
as(Z) on_opt(N) using_opt(U). {
- if( X==0 && Z.n==0 && N==0 && U==0 ){
+ if( A==0 && Z.n==0 && N==0 && U==0 ){
A = F;
}else if( F->nSrc==1 ){
- A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,0,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U);
if( A ){
struct SrcList_item *pNew = &A->a[A->nSrc-1];
struct SrcList_item *pOld = F->a;
@@ -646,7 +640,7 @@ seltablist(A) ::= stl_prefix(X) nm(Y) dbnm(D) LP exprlist(E) RP as(Z)
Select *pSubquery;
sqlite3SrcListShiftJoinType(F);
pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0,0);
- A = sqlite3SrcListAppendFromTerm(pParse,X,0,0,&Z,pSubquery,N,U);
+ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,N,U);
}
}
%endif SQLITE_OMIT_SUBQUERY
@@ -657,14 +651,17 @@ dbnm(A) ::= DOT nm(X). {A = X;}
%type fullname {SrcList*}
%destructor fullname {sqlite3SrcListDelete(pParse->db, $$);}
-fullname(A) ::= nm(X) dbnm(Y). {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y);}
+fullname(A) ::= nm(X) dbnm(Y).
+ {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); /*A-overwrites-X*/}
%type joinop {int}
joinop(X) ::= COMMA|JOIN. { X = JT_INNER; }
-joinop(X) ::= JOIN_KW(A) JOIN. { X = sqlite3JoinType(pParse,&A,0,0); }
-joinop(X) ::= JOIN_KW(A) nm(B) JOIN. { X = sqlite3JoinType(pParse,&A,&B,0); }
+joinop(X) ::= JOIN_KW(A) JOIN.
+ {X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/}
+joinop(X) ::= JOIN_KW(A) nm(B) JOIN.
+ {X = sqlite3JoinType(pParse,&A,&B,0); /*X-overwrites-A*/}
joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
- { X = sqlite3JoinType(pParse,&A,&B,&C); }
+ {X = sqlite3JoinType(pParse,&A,&B,&C);/*X-overwrites-A*/}
%type on_opt {Expr*}
%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);}
@@ -704,12 +701,12 @@ using_opt(U) ::= . {U = 0;}
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
-sortlist(A) ::= sortlist(X) COMMA expr(Y) sortorder(Z). {
- A = sqlite3ExprListAppend(pParse,X,Y.pExpr);
+sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
+ A = sqlite3ExprListAppend(pParse,A,Y.pExpr);
sqlite3ExprListSetSortOrder(A,Z);
}
sortlist(A) ::= expr(Y) sortorder(Z). {
- A = sqlite3ExprListAppend(pParse,0,Y.pExpr);
+ A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/
sqlite3ExprListSetSortOrder(A,Z);
}
@@ -799,8 +796,8 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
%type setlist {ExprList*}
%destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}
-setlist(A) ::= setlist(Z) COMMA nm(X) EQ expr(Y). {
- A = sqlite3ExprListAppend(pParse, Z, Y.pExpr);
+setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {
+ A = sqlite3ExprListAppend(pParse, A, Y.pExpr);
sqlite3ExprListSetName(pParse, A, &X, 1);
}
setlist(A) ::= nm(X) EQ expr(Y). {
@@ -831,10 +828,10 @@ insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
idlist_opt(A) ::= . {A = 0;}
idlist_opt(A) ::= LP idlist(X) RP. {A = X;}
-idlist(A) ::= idlist(X) COMMA nm(Y).
- {A = sqlite3IdListAppend(pParse->db,X,&Y);}
+idlist(A) ::= idlist(A) COMMA nm(Y).
+ {A = sqlite3IdListAppend(pParse->db,A,&Y);}
idlist(A) ::= nm(Y).
- {A = sqlite3IdListAppend(pParse->db,0,&Y);}
+ {A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/}
/////////////////////////// Expression Processing /////////////////////////////
//
@@ -858,61 +855,62 @@ idlist(A) ::= nm(Y).
** new Expr to populate pOut. Set the span of pOut to be the identifier
** that created the expression.
*/
- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token *pValue){
- pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, pValue);
- pOut->zStart = pValue->z;
- pOut->zEnd = &pValue->z[pValue->n];
+ static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
+ pOut->pExpr = sqlite3PExpr(pParse, op, 0, 0, &t);
+ pOut->zStart = t.z;
+ pOut->zEnd = &t.z[t.n];
}
}
-expr(A) ::= term(X). {A = X;}
-expr(A) ::= LP(B) expr(X) RP(E). {A.pExpr = X.pExpr; spanSet(&A,&B,&E);}
-term(A) ::= NULL(X). {spanExpr(&A, pParse, @X, &X);}
-expr(A) ::= id(X). {spanExpr(&A, pParse, TK_ID, &X);}
-expr(A) ::= JOIN_KW(X). {spanExpr(&A, pParse, TK_ID, &X);}
+expr(A) ::= term(A).
+expr(A) ::= LP(B) expr(X) RP(E).
+ {spanSet(&A,&B,&E); /*A-overwrites-B*/ A.pExpr = X.pExpr;}
+term(A) ::= NULL(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
+expr(A) ::= id(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
+expr(A) ::= JOIN_KW(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
expr(A) ::= nm(X) DOT nm(Y). {
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y);
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&A,&X,&Y);
}
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &X);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Y);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &Z);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
+ spanSet(&A,&X,&Z); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&A,&X,&Z);
}
-term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A, pParse, @X, &X);}
-term(A) ::= STRING(X). {spanExpr(&A, pParse, @X, &X);}
+term(A) ::= INTEGER|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
+term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X);/*A-overwrites-X*/}
expr(A) ::= VARIABLE(X). {
- if( X.n>=2 && X.z[0]=='#' && sqlite3Isdigit(X.z[1]) ){
+ Token t = X; /*A-overwrites-X*/
+ if( t.n>=2 && t.z[0]=='#' && sqlite3Isdigit(t.z[1]) ){
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
+ spanSet(&A, &t, &t);
if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &X);
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
A.pExpr = 0;
}else{
- A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &X);
- if( A.pExpr ) sqlite3GetInt32(&X.z[1], &A.pExpr->iTable);
+ A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &t);
+ if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable);
}
}else{
- spanExpr(&A, pParse, TK_VARIABLE, &X);
+ spanExpr(&A, pParse, TK_VARIABLE, t);
sqlite3ExprAssignVarNumber(pParse, A.pExpr);
}
- spanSet(&A, &X, &X);
}
-expr(A) ::= expr(E) COLLATE ids(C). {
- A.pExpr = sqlite3ExprAddCollateToken(pParse, E.pExpr, &C, 1);
- A.zStart = E.zStart;
+expr(A) ::= expr(A) COLLATE ids(C). {
+ A.pExpr = sqlite3ExprAddCollateToken(pParse, A.pExpr, &C, 1);
A.zEnd = &C.z[C.n];
}
%ifndef SQLITE_OMIT_CAST
expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_CAST, E.pExpr, 0, &T);
- spanSet(&A,&X,&Y);
}
%endif SQLITE_OMIT_CAST
expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
@@ -939,58 +937,56 @@ term(A) ::= CTIME_KW(OP). {
** objects and uses the result to populate a new ExprSpan object.
*/
static void spanBinaryExpr(
- ExprSpan *pOut, /* Write the result here */
Parse *pParse, /* The parsing context. Errors accumulate here */
int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand */
+ ExprSpan *pLeft, /* The left operand, and output */
ExprSpan *pRight /* The right operand */
){
- pOut->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
- pOut->zStart = pLeft->zStart;
- pOut->zEnd = pRight->zEnd;
+ pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr, 0);
+ pLeft->zEnd = pRight->zEnd;
}
/* If doNot is true, then add a TK_NOT Expr-node wrapper around the
** outside of *ppExpr.
*/
- static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){
- if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0);
+ static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
+ if( doNot ){
+ pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0, 0);
+ }
}
}
-expr(A) ::= expr(X) AND(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) OR(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) LT|GT|GE|LE(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) EQ|NE(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) PLUS|MINUS(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) STAR|SLASH|REM(OP) expr(Y).
- {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
-expr(A) ::= expr(X) CONCAT(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);}
+expr(A) ::= expr(A) AND(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) OR(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
+ {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
%type likeop {struct LikeOp}
-likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;}
+likeop(A) ::= LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 0;/*A-overwrites-X*/}
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A.eOperator = X; A.bNot = 1;}
-expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] {
+expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, A.pExpr);
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
- exprNot(pParse, OP.bNot, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, OP.bNot, &A);
A.zEnd = Y.zEnd;
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
}
-expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
+expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, X.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, A.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, E.pExpr);
A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator);
- exprNot(pParse, OP.bNot, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, OP.bNot, &A);
A.zEnd = E.zEnd;
if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
}
@@ -999,20 +995,18 @@ expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
/* Construct an expression node for a unary postfix operator
*/
static void spanUnaryPostfix(
- ExprSpan *pOut, /* Write the new expression node here */
Parse *pParse, /* Parsing context to record errors */
int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
+ ExprSpan *pOperand, /* The operand, and output */
Token *pPostOp /* The operand token for setting the span */
){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
- pOut->zStart = pOperand->zStart;
- pOut->zEnd = &pPostOp->z[pPostOp->n];
+ pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
+ pOperand->zEnd = &pPostOp->z[pPostOp->n];
}
}
-expr(A) ::= expr(X) ISNULL|NOTNULL(E). {spanUnaryPostfix(&A,pParse,@E,&X,&E);}
-expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
+expr(A) ::= expr(A) ISNULL|NOTNULL(E). {spanUnaryPostfix(pParse,@E,&A,&E);}
+expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);}
%include {
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
@@ -1033,12 +1027,12 @@ expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
// If expr2 is NULL then code as TK_ISNULL or TK_NOTNULL. If expr2
// is any other expression, code as TK_IS or TK_ISNOT.
//
-expr(A) ::= expr(X) IS expr(Y). {
- spanBinaryExpr(&A,pParse,TK_IS,&X,&Y);
+expr(A) ::= expr(A) IS expr(Y). {
+ spanBinaryExpr(pParse,TK_IS,&A,&Y);
binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_ISNULL);
}
-expr(A) ::= expr(X) IS NOT expr(Y). {
- spanBinaryExpr(&A,pParse,TK_ISNOT,&X,&Y);
+expr(A) ::= expr(A) IS NOT expr(Y). {
+ spanBinaryExpr(pParse,TK_ISNOT,&A,&Y);
binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_NOTNULL);
}
@@ -1052,42 +1046,43 @@ expr(A) ::= expr(X) IS NOT expr(Y). {
ExprSpan *pOperand, /* The operand */
Token *pPreOp /* The operand token for setting the span */
){
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zStart = pPreOp->z;
+ pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0, 0);
pOut->zEnd = pOperand->zEnd;
}
}
-expr(A) ::= NOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);}
-expr(A) ::= BITNOT(B) expr(X). {spanUnaryPrefix(&A,pParse,@B,&X,&B);}
+expr(A) ::= NOT(B) expr(X).
+ {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/}
+expr(A) ::= BITNOT(B) expr(X).
+ {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/}
expr(A) ::= MINUS(B) expr(X). [BITNOT]
- {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);}
+ {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);/*A-overwrites-B*/}
expr(A) ::= PLUS(B) expr(X). [BITNOT]
- {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);}
+ {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);/*A-overwrites-B*/}
%type between_op {int}
between_op(A) ::= BETWEEN. {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
-expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
+expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr);
- A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, W.pExpr, 0, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- exprNot(pParse, N, &A.pExpr);
- A.zStart = W.zStart;
+ exprNot(pParse, N, &A);
A.zEnd = Y.zEnd;
}
%ifndef SQLITE_OMIT_SUBQUERY
%type in_op {int}
in_op(A) ::= IN. {A = 0;}
in_op(A) ::= NOT IN. {A = 1;}
- expr(A) ::= expr(X) in_op(N) LP exprlist(Y) RP(E). [IN] {
+ expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP(E). [IN] {
if( Y==0 ){
/* Expressions of the form
**
@@ -1097,8 +1092,8 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
+ sqlite3ExprDelete(pParse->db, A.pExpr);
A.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[N]);
- sqlite3ExprDelete(pParse->db, X.pExpr);
}else if( Y->nExpr==1 ){
/* Expressions of the form:
**
@@ -1125,21 +1120,21 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, X.pExpr, pRHS, 0);
+ A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A.pExpr, pRHS, 0);
}else{
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = Y;
sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, Y);
}
- exprNot(pParse, N, &A.pExpr);
+ exprNot(pParse, N, &A);
}
- A.zStart = X.zStart;
A.zEnd = &E.z[E.n];
}
expr(A) ::= LP(B) select(X) RP(E). {
+ spanSet(&A,&B,&E); /*A-overwrites-B*/
A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = X;
@@ -1148,11 +1143,9 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SelectDelete(pParse->db, X);
}
- A.zStart = B.z;
- A.zEnd = &E.z[E.n];
}
- expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E). [IN] {
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
+ expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] {
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = Y;
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
@@ -1160,13 +1153,12 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SelectDelete(pParse->db, Y);
}
- exprNot(pParse, N, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, N, &A);
A.zEnd = &E.z[E.n];
}
- expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
+ expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z). [IN] {
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
- A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
+ A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0, 0);
if( A.pExpr ){
A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
@@ -1174,12 +1166,13 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- exprNot(pParse, N, &A.pExpr);
- A.zStart = X.zStart;
+ exprNot(pParse, N, &A);
A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
}
expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
- Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p;
+ spanSet(&A,&B,&E); /*A-overwrites-B*/
+ p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = Y;
ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
@@ -1187,13 +1180,12 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
}else{
sqlite3SelectDelete(pParse->db, Y);
}
- A.zStart = B.z;
- A.zEnd = &E.z[E.n];
}
%endif SQLITE_OMIT_SUBQUERY
/* CASE expressions */
expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
+ spanSet(&A,&C,&E); /*A-overwrites-C*/
A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
if( A.pExpr ){
A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
@@ -1202,13 +1194,11 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
sqlite3ExprListDelete(pParse->db, Y);
sqlite3ExprDelete(pParse->db, Z);
}
- A.zStart = C.z;
- A.zEnd = &E.z[E.n];
}
%type case_exprlist {ExprList*}
%destructor case_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
-case_exprlist(A) ::= case_exprlist(X) WHEN expr(Y) THEN expr(Z). {
- A = sqlite3ExprListAppend(pParse,X, Y.pExpr);
+case_exprlist(A) ::= case_exprlist(A) WHEN expr(Y) THEN expr(Z). {
+ A = sqlite3ExprListAppend(pParse,A, Y.pExpr);
A = sqlite3ExprListAppend(pParse,A, Z.pExpr);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
@@ -1221,7 +1211,7 @@ case_else(A) ::= ELSE expr(X). {A = X.pExpr;}
case_else(A) ::= . {A = 0;}
%type case_operand {Expr*}
%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);}
-case_operand(A) ::= expr(X). {A = X.pExpr;}
+case_operand(A) ::= expr(X). {A = X.pExpr; /*A-overwrites-X*/}
case_operand(A) ::= . {A = 0;}
%type exprlist {ExprList*}
@@ -1229,12 +1219,12 @@ case_operand(A) ::= . {A = 0;}
%type nexprlist {ExprList*}
%destructor nexprlist {sqlite3ExprListDelete(pParse->db, $$);}
-exprlist(A) ::= nexprlist(X). {A = X;}
+exprlist(A) ::= nexprlist(A).
exprlist(A) ::= . {A = 0;}
-nexprlist(A) ::= nexprlist(X) COMMA expr(Y).
- {A = sqlite3ExprListAppend(pParse,X,Y.pExpr);}
+nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
+ {A = sqlite3ExprListAppend(pParse,A,Y.pExpr);}
nexprlist(A) ::= expr(Y).
- {A = sqlite3ExprListAppend(pParse,0,Y.pExpr);}
+ {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
///////////////////////////// The CREATE INDEX command ///////////////////////
@@ -1298,11 +1288,11 @@ uniqueflag(A) ::= . {A = OE_None;}
eidlist_opt(A) ::= . {A = 0;}
eidlist_opt(A) ::= LP eidlist(X) RP. {A = X;}
-eidlist(A) ::= eidlist(X) COMMA nm(Y) collate(C) sortorder(Z). {
- A = parserAddExprIdListTerm(pParse, X, &Y, C, Z);
+eidlist(A) ::= eidlist(A) COMMA nm(Y) collate(C) sortorder(Z). {
+ A = parserAddExprIdListTerm(pParse, A, &Y, C, Z);
}
eidlist(A) ::= nm(Y) collate(C) sortorder(Z). {
- A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z);
+ A = parserAddExprIdListTerm(pParse, 0, &Y, C, Z); /*A-overwrites-Y*/
}
%type collate {int}
@@ -1334,15 +1324,15 @@ cmd ::= PRAGMA nm(X) dbnm(Z) EQ minus_num(Y).
cmd ::= PRAGMA nm(X) dbnm(Z) LP minus_num(Y) RP.
{sqlite3Pragma(pParse,&X,&Z,&Y,1);}
-nmnum(A) ::= plus_num(X). {A = X;}
-nmnum(A) ::= nm(X). {A = X;}
-nmnum(A) ::= ON(X). {A = X;}
-nmnum(A) ::= DELETE(X). {A = X;}
-nmnum(A) ::= DEFAULT(X). {A = X;}
+nmnum(A) ::= plus_num(A).
+nmnum(A) ::= nm(A).
+nmnum(A) ::= ON(A).
+nmnum(A) ::= DELETE(A).
+nmnum(A) ::= DEFAULT(A).
%endif SQLITE_OMIT_PRAGMA
%token_class number INTEGER|FLOAT.
plus_num(A) ::= PLUS number(X). {A = X;}
-plus_num(A) ::= number(X). {A = X;}
+plus_num(A) ::= number(A).
minus_num(A) ::= MINUS number(X). {A = X;}
//////////////////////////// The CREATE TRIGGER command /////////////////////
@@ -1359,7 +1349,7 @@ trigger_decl(A) ::= temp(T) TRIGGER ifnotexists(NOERR) nm(B) dbnm(Z)
trigger_time(C) trigger_event(D)
ON fullname(E) foreach_clause when_clause(G). {
sqlite3BeginTrigger(pParse, &B, &Z, C, D.a, D.b, E, G, T, NOERR);
- A = (Z.n==0?B:Z);
+ A = (Z.n==0?B:Z); /*A-overwrites-T*/
}
%type trigger_time {int}
@@ -1370,9 +1360,9 @@ trigger_time(A) ::= . { A = TK_BEFORE; }
%type trigger_event {struct TrigEvent}
%destructor trigger_event {sqlite3IdListDelete(pParse->db, $$.b);}
-trigger_event(A) ::= DELETE|INSERT(OP). {A.a = @OP; A.b = 0;}
-trigger_event(A) ::= UPDATE(OP). {A.a = @OP; A.b = 0;}
-trigger_event(A) ::= UPDATE OF idlist(X). {A.a = TK_UPDATE; A.b = X;}
+trigger_event(A) ::= DELETE|INSERT(X). {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
+trigger_event(A) ::= UPDATE(X). {A.a = @X; /*A-overwrites-X*/ A.b = 0;}
+trigger_event(A) ::= UPDATE OF idlist(X).{A.a = TK_UPDATE; A.b = X;}
foreach_clause ::= .
foreach_clause ::= FOR EACH ROW.
@@ -1384,16 +1374,14 @@ when_clause(A) ::= WHEN expr(X). { A = X.pExpr; }
%type trigger_cmd_list {TriggerStep*}
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep(pParse->db, $$);}
-trigger_cmd_list(A) ::= trigger_cmd_list(Y) trigger_cmd(X) SEMI. {
- assert( Y!=0 );
- Y->pLast->pNext = X;
- Y->pLast = X;
- A = Y;
+trigger_cmd_list(A) ::= trigger_cmd_list(A) trigger_cmd(X) SEMI. {
+ assert( A!=0 );
+ A->pLast->pNext = X;
+ A->pLast = X;
}
-trigger_cmd_list(A) ::= trigger_cmd(X) SEMI. {
- assert( X!=0 );
- X->pLast = X;
- A = X;
+trigger_cmd_list(A) ::= trigger_cmd(A) SEMI. {
+ assert( A!=0 );
+ A->pLast = A;
}
// Disallow qualified table names on INSERT, UPDATE, and DELETE statements
@@ -1401,7 +1389,7 @@ trigger_cmd_list(A) ::= trigger_cmd(X) SEMI. {
// the same database as the table that the trigger fires on.
//
%type trnm {Token}
-trnm(A) ::= nm(X). {A = X;}
+trnm(A) ::= nm(A).
trnm(A) ::= nm DOT nm(X). {
A = X;
sqlite3ErrorMsg(pParse,
@@ -1432,35 +1420,34 @@ tridxby ::= NOT INDEXED. {
// UPDATE
trigger_cmd(A) ::=
UPDATE orconf(R) trnm(X) tridxby SET setlist(Y) where_opt(Z).
- { A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }
+ {A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R);}
// INSERT
trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) idlist_opt(F) select(S).
- {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);}
+ {A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);/*A-overwrites-R*/}
// DELETE
trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
- {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);}
+ {A = sqlite3TriggerDeleteStep(pParse->db, &X, Y);}
// SELECT
-trigger_cmd(A) ::= select(X). {A = sqlite3TriggerSelectStep(pParse->db, X); }
+trigger_cmd(A) ::= select(X).
+ {A = sqlite3TriggerSelectStep(pParse->db, X); /*A-overwrites-X*/}
// The special RAISE expression that may occur in trigger programs
expr(A) ::= RAISE(X) LP IGNORE RP(Y). {
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
if( A.pExpr ){
A.pExpr->affinity = OE_Ignore;
}
- A.zStart = X.z;
- A.zEnd = &Y.z[Y.n];
}
expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). {
+ spanSet(&A,&X,&Y); /*A-overwrites-X*/
A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &Z);
if( A.pExpr ) {
A.pExpr->affinity = (char)T;
}
- A.zStart = X.z;
- A.zEnd = &Y.z[Y.n];
}
%endif !SQLITE_OMIT_TRIGGER
@@ -1556,9 +1543,9 @@ with(A) ::= WITH wqlist(W). { A = W; }
with(A) ::= WITH RECURSIVE wqlist(W). { A = W; }
wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
- A = sqlite3WithAdd(pParse, 0, &X, Y, Z);
+ A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/
}
-wqlist(A) ::= wqlist(W) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
- A = sqlite3WithAdd(pParse, W, &X, Y, Z);
+wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. {
+ A = sqlite3WithAdd(pParse, A, &X, Y, Z);
}
%endif SQLITE_OMIT_CTE
diff --git a/src/pcache.c b/src/pcache.c
index 5ac9d34a1e..61e7587422 100644
--- a/src/pcache.c
+++ b/src/pcache.c
@@ -191,7 +191,7 @@ int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
pCache->bPurgeable
);
- if( pNew==0 ) return SQLITE_NOMEM;
+ if( pNew==0 ) return SQLITE_NOMEM_BKPT;
sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
if( pCache->pCache ){
sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
@@ -301,7 +301,7 @@ int sqlite3PcacheFetchStress(
}
}
*ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
- return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+ return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK;
}
/*
diff --git a/src/prepare.c b/src/prepare.c
index f74aa52e0b..6685dfeaf7 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -33,7 +33,7 @@ static void corruptSchema(
sqlite3DbFree(db, *pData->pzErrMsg);
*pData->pzErrMsg = z;
}
- pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
+ pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT;
}
/*
@@ -307,7 +307,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
#endif
}
if( db->mallocFailed ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
sqlite3ResetAllSchemasOfConnection(db);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
@@ -524,7 +524,7 @@ static int sqlite3Prepare(
/* Allocate the parsing context */
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto end_prepare;
}
pParse->pReprepare = pReprepare;
@@ -601,7 +601,7 @@ static int sqlite3Prepare(
schemaIsValid(pParse);
}
if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM_BKPT;
}
if( pzTail ){
*pzTail = pParse->zTail;
diff --git a/src/resolve.c b/src/resolve.c
index 81bb712a2e..8e290af123 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -656,9 +656,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "functions", NC_PartIdx);
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
- pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
+ pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
if( pDef==0 ){
- pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
+ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
if( pDef==0 ){
no_such_func = 1;
}else{
diff --git a/src/select.c b/src/select.c
index c3132c2325..bde278b43c 100644
--- a/src/select.c
+++ b/src/select.c
@@ -105,7 +105,7 @@ Select *sqlite3SelectNew(
ExprList *pGroupBy, /* the GROUP BY clause */
Expr *pHaving, /* the HAVING clause */
ExprList *pOrderBy, /* the ORDER BY clause */
- u16 selFlags, /* Flag parameters, such as SF_Distinct */
+ u32 selFlags, /* Flag parameters, such as SF_Distinct */
Expr *pLimit, /* LIMIT value. NULL means not used */
Expr *pOffset /* OFFSET value. NULL means no offset */
){
@@ -1688,7 +1688,7 @@ int sqlite3ColumnsFromExprList(
sqlite3DbFree(db, aCol);
*paCol = 0;
*pnCol = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
return SQLITE_OK;
}
@@ -1845,8 +1845,9 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
VdbeComment((v, "LIMIT counter"));
if( n==0 ){
sqlite3VdbeGoto(v, iBreak);
- }else if( n>=0 && p->nSelectRow>(u64)n ){
- p->nSelectRow = n;
+ }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){
+ p->nSelectRow = sqlite3LogEst((u64)n);
+ p->selFlags |= SF_FixedLimit;
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
@@ -2287,12 +2288,12 @@ static int multiSelect(
testcase( rc!=SQLITE_OK );
pDelete = p->pPrior;
p->pPrior = pPrior;
- p->nSelectRow += pPrior->nSelectRow;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
if( pPrior->pLimit
&& sqlite3ExprIsInteger(pPrior->pLimit, &nLimit)
- && nLimit>0 && p->nSelectRow > (u64)nLimit
+ && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit)
){
- p->nSelectRow = nLimit;
+ p->nSelectRow = sqlite3LogEst((u64)nLimit);
}
if( addr ){
sqlite3VdbeJumpHere(v, addr);
@@ -2364,7 +2365,9 @@ static int multiSelect(
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
- if( p->op==TK_UNION ) p->nSelectRow += pPrior->nSelectRow;
+ if( p->op==TK_UNION ){
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
+ }
sqlite3ExprDelete(db, p->pLimit);
p->pLimit = pLimit;
p->pOffset = pOffset;
@@ -2499,7 +2502,7 @@ static int multiSelect(
nCol = p->pEList->nExpr;
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto multi_select_end;
}
for(i=0, apColl=pKeyInfo->aColl; iflags |= EP_IntValue;
pNew->u.iValue = i;
pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
@@ -3001,7 +3004,7 @@ static int multiSelectOrderBy(
addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
VdbeCoverage(v);
sqlite3VdbeGoto(v, addrEofA);
- p->nSelectRow += pPrior->nSelectRow;
+ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow);
}
/* Generate a subroutine to run when the results from select B
@@ -4091,7 +4094,7 @@ static int withExpand(
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
- if( db->mallocFailed ) return SQLITE_NOMEM;
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
assert( pFrom->pSelect );
/* Check if this is a recursive CTE. */
@@ -4987,7 +4990,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
pItem->fg.viaCoroutine = 1;
pItem->regResult = dest.iSdst;
sqlite3VdbeEndCoroutine(v, pItem->regReturn);
@@ -5018,7 +5021,7 @@ int sqlite3Select(
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
- pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow);
+ pItem->pTab->nRowLogEst = pSub->nSelectRow;
if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
VdbeComment((v, "end %s", pItem->pTab->zName));
@@ -5101,7 +5104,7 @@ int sqlite3Select(
/* Set the limiter.
*/
iEnd = sqlite3VdbeMakeLabel(v);
- p->nSelectRow = LARGEST_INT64;
+ p->nSelectRow = 320; /* 4 billion rows */
computeLimitRegisters(pParse, p, iEnd);
if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
@@ -5125,10 +5128,12 @@ int sqlite3Select(
if( !isAgg && pGroupBy==0 ){
/* No aggregate functions and no GROUP BY clause */
u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0);
+ assert( WHERE_USE_LIMIT==SF_FixedLimit );
+ wctrlFlags |= p->selFlags & SF_FixedLimit;
/* Begin the database scan. */
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
- p->pEList, wctrlFlags, 0);
+ p->pEList, wctrlFlags, p->nSelectRow);
if( pWInfo==0 ) goto select_end;
if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){
p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo);
@@ -5188,9 +5193,11 @@ int sqlite3Select(
for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){
pItem->u.x.iAlias = 0;
}
- if( p->nSelectRow>100 ) p->nSelectRow = 100;
+ assert( 66==sqlite3LogEst(100) );
+ if( p->nSelectRow>66 ) p->nSelectRow = 66;
}else{
- p->nSelectRow = 1;
+ assert( 0==sqlite3LogEst(1) );
+ p->nSelectRow = 0;
}
/* If there is both a GROUP BY and an ORDER BY clause and they are
diff --git a/src/shell.c b/src/shell.c
index 2988f48d0c..1cf9eb447f 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -3260,7 +3260,7 @@ static int do_meta_command(char *zLine, ShellState *p){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
while( xRead(&sCtx) ){
- zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
+ zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
cSep = ',';
if( sCtx.cTerm!=sCtx.cColSep ) break;
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index bf0dad4cb0..a790d77975 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -7489,7 +7489,7 @@ void sqlite3_log(int iErrCode, const char *zFormat, ...);
** previously registered write-ahead log callback. ^Note that the
** [sqlite3_wal_autocheckpoint()] interface and the
** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
-** those overwrite any prior [sqlite3_wal_hook()] settings.
+** overwrite any prior [sqlite3_wal_hook()] settings.
*/
void *sqlite3_wal_hook(
sqlite3*,
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index e15c681a01..5ac33b4de6 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -15,6 +15,14 @@
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
+/*
+** Make sure that rand_s() is available on Windows systems with MSVC 2005
+** or higher.
+*/
+#if defined(_MSC_VER) && _MSC_VER>=1400
+# define _CRT_RAND_S
+#endif
+
/*
** Include the header file used to customize the compiler options for MSVC.
** This should be done first so that it can successfully prevent spurious
@@ -149,7 +157,7 @@
** to the next, so we have developed the following set of #if statements
** to generate appropriate macros for a wide range of compilers.
**
-** The correct "ANSI" way to do this is to use the intptr_t type.
+** The correct "ANSI" way to do this is to use the intptr_t type.
** Unfortunately, that typedef is not available on all compilers, or
** if it is available, it requires an #include of specific headers
** that vary from one machine to the next.
@@ -316,7 +324,7 @@
** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
** feature.
*/
-#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
+#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
@@ -331,7 +339,7 @@
#endif
/*
-** The testcase() macro is used to aid in coverage testing. When
+** The testcase() macro is used to aid in coverage testing. When
** doing coverage testing, the condition inside the argument to
** testcase() must be evaluated both true and false in order to
** get full branch coverage. The testcase() macro is inserted
@@ -377,7 +385,7 @@
#endif
/*
-** The ALWAYS and NEVER macros surround boolean expressions which
+** The ALWAYS and NEVER macros surround boolean expressions which
** are intended to always be true or false, respectively. Such
** expressions could be omitted from the code completely. But they
** are included in a few cases in order to enhance the resilience
@@ -490,7 +498,7 @@
/*
** OMIT_TEMPDB is set to 1 if SQLITE_OMIT_TEMPDB is defined, or 0
-** afterward. Having this macro allows us to cause the C compiler
+** afterward. Having this macro allows us to cause the C compiler
** to omit code used by TEMP tables without messy #ifndef statements.
*/
#ifdef SQLITE_OMIT_TEMPDB
@@ -529,7 +537,7 @@
/*
** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
-** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
+** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it
** to zero.
*/
#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
@@ -677,7 +685,7 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */
** 4 -> 20 1000 -> 99 1048576 -> 200
** 10 -> 33 1024 -> 100 4294967296 -> 320
**
-** The LogEst can be negative to indicate fractional values.
+** The LogEst can be negative to indicate fractional values.
** Examples:
**
** 0.5 -> -10 0.1 -> -33 0.0625 -> -40
@@ -743,7 +751,7 @@ typedef INT16_TYPE LogEst;
#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32))
#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64)
-/*
+/*
** Round up a number to the next larger multiple of 8. This is used
** to force 8-byte alignment on 64-bit architectures.
*/
@@ -837,7 +845,7 @@ typedef INT16_TYPE LogEst;
/*
** An instance of the following structure is used to store the busy-handler
-** callback for a given sqlite handle.
+** callback for a given sqlite handle.
**
** The sqlite.busyHandler member of the sqlite struct contains the busy
** callback for the database handle. Each pager opened via the sqlite
@@ -882,9 +890,9 @@ struct BusyHandler {
/*
** The following value as a destructor means to use sqlite3DbFree().
-** The sqlite3DbFree() routine requires two parameters instead of the
-** one parameter that destructors normally want. So we have to introduce
-** this magic value that the code knows to handle differently. Any
+** The sqlite3DbFree() routine requires two parameters instead of the
+** one parameter that destructors normally want. So we have to introduce
+** this magic value that the code knows to handle differently. Any
** pointer will work here as long as it is distinct from SQLITE_STATIC
** and SQLITE_TRANSIENT.
*/
@@ -911,16 +919,16 @@ struct BusyHandler {
int sqlite3_wsd_init(int N, int J);
void *sqlite3_wsd_find(void *K, int L);
#else
- #define SQLITE_WSD
+ #define SQLITE_WSD
#define GLOBAL(t,v) v
#define sqlite3GlobalConfig sqlite3Config
#endif
/*
** The following macros are used to suppress compiler warnings and to
-** make it clear to human readers when a function parameter is deliberately
+** make it clear to human readers when a function parameter is deliberately
** left unused within the body of a function. This usually happens when
-** a function is called via a function pointer. For example the
+** a function is called via a function pointer. For example the
** implementation of an SQL aggregate step callback may not use the
** parameter indicating the number of arguments passed to the aggregate,
** if it knows that this is enforced elsewhere.
@@ -987,7 +995,7 @@ typedef struct WhereInfo WhereInfo;
typedef struct With With;
/*
-** Defer sourcing vdbe.h and btree.h until after the "u8" and
+** Defer sourcing vdbe.h and btree.h until after the "u8" and
** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque
** pointer types (i.e. FuncDef) defined above.
*/
@@ -1021,7 +1029,7 @@ struct Db {
** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
** In shared cache mode, a single Schema object can be shared by multiple
** Btrees that refer to the same underlying BtShared object.
-**
+**
** Schema objects are automatically deallocated when the last Btree that
** references them is destroyed. The TEMP Schema is manually freed by
** sqlite3_close().
@@ -1046,7 +1054,7 @@ struct Schema {
};
/*
-** These macros can be used to test, set, or clear bits in the
+** These macros can be used to test, set, or clear bits in the
** Db.pSchema->flags field.
*/
#define DbHasProperty(D,I,P) (((D)->aDb[I].pSchema->schemaFlags&(P))==(P))
@@ -1110,13 +1118,15 @@ struct LookasideSlot {
};
/*
-** A hash table for function definitions.
+** A hash table for built-in function definitions. (Application-defined
+** functions use a regular table table from hash.h.)
**
** Hash each FuncDef structure into one of the FuncDefHash.a[] slots.
-** Collisions are on the FuncDef.pHash chain.
+** Collisions are on the FuncDef.u.pHash chain.
*/
+#define SQLITE_FUNC_HASH_SZ 23
struct FuncDefHash {
- FuncDef *a[23]; /* Hash table for functions */
+ FuncDef *a[SQLITE_FUNC_HASH_SZ]; /* Hash table for functions */
};
#ifdef SQLITE_USER_AUTHENTICATION
@@ -1209,9 +1219,9 @@ struct sqlite3 {
void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */
- void *pCommitArg; /* Argument to xCommitCallback() */
+ void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
- void *pRollbackArg; /* Argument to xRollbackCallback() */
+ void *pRollbackArg; /* Argument to xRollbackCallback() */
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
@@ -1251,7 +1261,7 @@ struct sqlite3 {
VTable **aVTrans; /* Virtual tables with open transactions */
VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */
#endif
- FuncDefHash aFunc; /* Hash table of connection functions */
+ Hash aFunc; /* Hash table of connection functions */
Hash aCollSeq; /* All collating sequences */
BusyHandler busyHandler; /* Busy callback */
Db aDbStatic[2]; /* Static space for the 2 default backends */
@@ -1263,8 +1273,8 @@ struct sqlite3 {
i64 nDeferredImmCons; /* Net deferred immediate constraints */
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
- /* The following variables are all protected by the STATIC_MASTER
- ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
+ /* The following variables are all protected by the STATIC_MASTER
+ ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
**
** When X.pUnlockConnection==Y, that means that X is waiting for Y to
** unlock so that it can proceed.
@@ -1378,27 +1388,33 @@ struct sqlite3 {
/*
** Each SQL function is defined by an instance of the following
-** structure. A pointer to this structure is stored in the sqlite.aFunc
-** hash table. When multiple functions have the same name, the hash table
-** points to a linked list of these structures.
+** structure. For global built-in functions (ex: substr(), max(), count())
+** a pointer to this structure is held in the sqlite3BuiltinFunctions object.
+** For per-connection application-defined functions, a pointer to this
+** structure is held in the db->aHash hash table.
+**
+** The u.pHash field is used by the global built-ins. The u.pDestructor
+** field is used by per-connection app-def functions.
*/
struct FuncDef {
- i16 nArg; /* Number of arguments. -1 means unlimited */
+ i8 nArg; /* Number of arguments. -1 means unlimited */
u16 funcFlags; /* Some combination of SQLITE_FUNC_* */
void *pUserData; /* User data parameter */
FuncDef *pNext; /* Next function with same name */
void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
- char *zName; /* SQL name of the function. */
- FuncDef *pHash; /* Next with a different name but the same hash */
- FuncDestructor *pDestructor; /* Reference counted destructor function */
+ const char *zName; /* SQL name of the function. */
+ union {
+ FuncDef *pHash; /* Next with a different name but the same hash */
+ FuncDestructor *pDestructor; /* Reference counted destructor function */
+ } u;
};
/*
** This structure encapsulates a user-function destructor callback (as
** configured using create_function_v2()) and a reference counter. When
** create_function_v2() is called to create a function with a destructor,
-** a single object of this type is allocated. FuncDestructor.nRef is set to
+** a single object of this type is allocated. FuncDestructor.nRef is set to
** the number of FuncDef objects created (either 1 or 3, depending on whether
** or not the specified encoding is SQLITE_ANY). The FuncDef.pDestructor
** member of each of the new FuncDef objects is set to point to the allocated
@@ -1440,10 +1456,10 @@ struct FuncDestructor {
** used to create the initializers for the FuncDef structures.
**
** FUNCTION(zName, nArg, iArg, bNC, xFunc)
-** Used to create a scalar function definition of a function zName
+** Used to create a scalar function definition of a function zName
** implemented by C function xFunc that accepts nArg arguments. The
** value passed as iArg is cast to a (void*) and made available
-** as the user-data (sqlite3_user_data()) for the function. If
+** as the user-data (sqlite3_user_data()) for the function. If
** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set.
**
** VFUNCTION(zName, nArg, iArg, bNC, xFunc)
@@ -1462,8 +1478,8 @@ struct FuncDestructor {
** FUNCTION().
**
** LIKEFUNC(zName, nArg, pArg, flags)
-** Used to create a scalar function definition of a function zName
-** that accepts nArg arguments and is implemented by a call to C
+** Used to create a scalar function definition of a function zName
+** that accepts nArg arguments and is implemented by a call to C
** function likeFunc. Argument pArg is cast to a (void *) and made
** available as the function user-data (sqlite3_user_data()). The
** FuncDef.flags variable is set to the value passed as the flags
@@ -1471,28 +1487,28 @@ struct FuncDestructor {
*/
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
{nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
- SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, 0, 0}
+ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, #zName, {0} }
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
- pArg, 0, xFunc, 0, #zName, 0, 0}
+ pArg, 0, xFunc, 0, #zName, }
#define LIKEFUNC(zName, nArg, arg, flags) \
{nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
- (void *)arg, 0, likeFunc, 0, #zName, 0, 0}
+ (void *)arg, 0, likeFunc, 0, #zName, {0} }
#define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
{nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
- SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName,0,0}
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#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,#zName,0,0}
+ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,#zName, {0}}
/*
** All current savepoints are stored in a linked list starting at
@@ -1579,7 +1595,7 @@ struct CollSeq {
**
** These used to have mnemonic name like 'i' for SQLITE_AFF_INTEGER and
** 't' for SQLITE_AFF_TEXT. But we can save a little space and improve
-** the speed a little by numbering the values consecutively.
+** the speed a little by numbering the values consecutively.
**
** But rather than start with 0 or 1, we begin with 'A'. That way,
** when multiple affinity types are concatenated into a string and
@@ -1598,7 +1614,7 @@ struct CollSeq {
/*
** The SQLITE_AFF_MASK values masks off the significant bits of an
-** affinity value.
+** affinity value.
*/
#define SQLITE_AFF_MASK 0x47
@@ -1618,20 +1634,20 @@ struct CollSeq {
/*
** An object of this type is created for each virtual table present in
-** the database schema.
+** the database schema.
**
** If the database schema is shared, then there is one instance of this
** structure for each database connection (sqlite3*) that uses the shared
** schema. This is because each database connection requires its own unique
-** instance of the sqlite3_vtab* handle used to access the virtual table
-** implementation. sqlite3_vtab* handles can not be shared between
-** database connections, even when the rest of the in-memory database
+** instance of the sqlite3_vtab* handle used to access the virtual table
+** implementation. sqlite3_vtab* handles can not be shared between
+** database connections, even when the rest of the in-memory database
** schema is shared, as the implementation often stores the database
** connection handle passed to it via the xConnect() or xCreate() method
** during initialization internally. This database connection handle may
-** then be used by the virtual table implementation to access real tables
-** within the database. So that they appear as part of the callers
-** transaction, these accesses need to be made via the same database
+** then be used by the virtual table implementation to access real tables
+** within the database. So that they appear as part of the callers
+** transaction, these accesses need to be made via the same database
** connection as that used to execute SQL operations on the virtual table.
**
** All VTable objects that correspond to a single table in a shared
@@ -1643,19 +1659,19 @@ struct CollSeq {
** sqlite3_vtab* handle in the compiled query.
**
** When an in-memory Table object is deleted (for example when the
-** schema is being reloaded for some reason), the VTable objects are not
-** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
+** schema is being reloaded for some reason), the VTable objects are not
+** deleted and the sqlite3_vtab* handles are not xDisconnect()ed
** immediately. Instead, they are moved from the Table.pVTable list to
** another linked list headed by the sqlite3.pDisconnect member of the
-** corresponding sqlite3 structure. They are then deleted/xDisconnected
+** corresponding sqlite3 structure. They are then deleted/xDisconnected
** next time a statement is prepared using said sqlite3*. This is done
** to avoid deadlock issues involving multiple sqlite3.mutex mutexes.
** Refer to comments above function sqlite3VtabUnlockList() for an
** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect
** list without holding the corresponding sqlite3.mutex mutex.
**
-** The memory for objects of this type is always allocated by
-** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
+** The memory for objects of this type is always allocated by
+** sqlite3DbMalloc(), using the connection handle stored in VTable.db as
** the first argument.
*/
struct VTable {
@@ -1823,7 +1839,7 @@ struct FKey {
** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
** referenced table row is propagated into the row that holds the
** foreign key.
-**
+**
** The following symbolic values are used to record which type
** of action to take.
*/
@@ -1844,7 +1860,7 @@ struct FKey {
/*
** An instance of the following structure is passed as the first
-** argument to sqlite3VdbeKeyCompare and is used to control the
+** argument to sqlite3VdbeKeyCompare and is used to control the
** comparison of the two index keys.
**
** Note that aSortOrder[] and aColl[] have nField+1 slots. There
@@ -1885,7 +1901,7 @@ struct KeyInfo {
** The key comparison functions actually return default_rc when they find
** an equals comparison. default_rc can be -1, 0, or +1. If there are
** multiple entries in the b-tree with the same key (when only looking
-** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
+** at the first pKeyInfo->nFields,) then default_rc can be set to -1 to
** cause the search to find the last match, or +1 to cause the search to
** find the first match.
**
@@ -1922,7 +1938,7 @@ struct UnpackedRecord {
** In the Table structure describing Ex1, nCol==3 because there are
** three columns in the table. In the Index structure describing
** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
-** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
+** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
** The second column to be indexed (c1) has an index of 0 in
** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
@@ -1930,7 +1946,7 @@ struct UnpackedRecord {
** The Index.onError field determines whether or not the indexed columns
** must be unique and what to do if they are not. When Index.onError=OE_None,
** it means this is not a unique index. Otherwise it is a unique index
-** and the value of Index.onError indicate the which conflict resolution
+** and the value of Index.onError indicate the which conflict resolution
** algorithm to employ whenever an attempt is made to insert a non-unique
** element.
**
@@ -1995,7 +2011,7 @@ struct Index {
#define XN_EXPR (-2) /* Indexed column is an expression */
/*
-** Each sample stored in the sqlite_stat3 table is represented in memory
+** Each sample stored in the sqlite_stat3 table is represented in memory
** using a structure of this type. See documentation at the top of the
** analyze.c source file for additional information.
*/
@@ -2090,9 +2106,9 @@ typedef int ynVar;
** to represent the greater-than-or-equal-to operator in the expression
** tree.
**
-** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
+** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
** or TK_STRING), then Expr.token contains the text of the SQL literal. If
-** the expression is a variable (TK_VARIABLE), then Expr.token contains the
+** the expression is a variable (TK_VARIABLE), then Expr.token contains the
** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
** then Expr.token contains the name of the function.
**
@@ -2103,7 +2119,7 @@ typedef int ynVar;
** a CASE expression or an IN expression of the form " IN (, ...)".
** Expr.x.pSelect is used if the expression is a sub-select or an expression of
** the form " IN (SELECT ...)". If the EP_xIsSelect bit is set in the
-** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
+** Expr.flags mask, then Expr.x.pSelect is valid. Otherwise, Expr.x.pList is
** valid.
**
** An expression of the form ID or ID.ID refers to a column in a table.
@@ -2114,8 +2130,8 @@ typedef int ynVar;
** value is also stored in the Expr.iAgg column in the aggregate so that
** it can be accessed after all aggregates are computed.
**
-** If the expression is an unbound variable marker (a question mark
-** character '?' in the original SQL) then the Expr.iTable holds the index
+** If the expression is an unbound variable marker (a question mark
+** character '?' in the original SQL) then the Expr.iTable holds the index
** number for that variable.
**
** If the expression is a subquery then Expr.iColumn holds an integer
@@ -2154,7 +2170,7 @@ struct Expr {
/* If the EP_TokenOnly flag is set in the Expr.flags mask, then no
** space is allocated for the fields below this point. An attempt to
- ** access them will result in a segfault or malfunction.
+ ** access them will result in a segfault or malfunction.
*********************************************************************/
Expr *pLeft; /* Left subnode */
@@ -2220,7 +2236,7 @@ struct Expr {
#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
/*
-** These macros can be used to test, set, or clear bits in the
+** These macros can be used to test, set, or clear bits in the
** Expr.flags field.
*/
#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
@@ -2239,8 +2255,8 @@ struct Expr {
#endif
/*
-** Macros to determine the number of bytes required by a normal Expr
-** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
+** Macros to determine the number of bytes required by a normal Expr
+** struct, an Expr struct with the EP_Reduced flag set in Expr.flags
** and an Expr struct with the EP_TokenOnly flag set.
*/
#define EXPR_FULLSIZE sizeof(Expr) /* Full size */
@@ -2248,7 +2264,7 @@ struct Expr {
#define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */
/*
-** Flags passed to the sqlite3ExprDup() function. See the header comment
+** Flags passed to the sqlite3ExprDup() function. See the header comment
** above sqlite3ExprDup() for details.
*/
#define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */
@@ -2330,7 +2346,11 @@ struct IdList {
** tables in a join to 32 instead of 64. But it also reduces the size
** of the library by 738 bytes on ix86.
*/
-typedef u64 Bitmask;
+#ifdef SQLITE_BITMASK_TYPE
+ typedef SQLITE_BITMASK_TYPE Bitmask;
+#else
+ typedef u64 Bitmask;
+#endif
/*
** The number of bits in a Bitmask. "BMS" means "BitMask Size".
@@ -2430,6 +2450,7 @@ struct SrcList {
#define WHERE_SORTBYGROUP 0x0800 /* Support sqlite3WhereIsSorted() */
#define WHERE_REOPEN_IDX 0x1000 /* Try to use OP_ReopenIdx */
#define WHERE_ONEPASS_MULTIROW 0x2000 /* ONEPASS is ok with multiple rows */
+#define WHERE_USE_LIMIT 0x4000 /* There is a constant LIMIT clause */
/* Allowed return values from sqlite3WhereIsDistinct()
*/
@@ -2447,12 +2468,12 @@ struct SrcList {
** pEList corresponds to the result set of a SELECT and is NULL for
** other statements.
**
-** NameContexts can be nested. When resolving names, the inner-most
+** NameContexts can be nested. When resolving names, the inner-most
** context is searched first. If no match is found, the next outer
** context is checked. If there is still no match, the next context
** is checked. This process continues until either a match is found
** or all contexts are check. When a match is found, the nRef member of
-** the context containing the match is incremented.
+** the context containing the match is incremented.
**
** Each subquery gets a new NameContext. The pNext field points to the
** NameContext in the parent query. Thus the process of scanning the
@@ -2475,7 +2496,7 @@ struct NameContext {
**
** Note: NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
** SQLITE_FUNC_MINMAX.
-**
+**
*/
#define NC_AllowAgg 0x0001 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x0002 /* One or more aggregate functions seen */
@@ -2508,13 +2529,13 @@ struct NameContext {
struct Select {
ExprList *pEList; /* The fields of the result */
u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
- u16 selFlags; /* Various SF_* values */
+ LogEst nSelectRow; /* Estimated number of result rows */
+ u32 selFlags; /* Various SF_* values */
int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
#if SELECTTRACE_ENABLED
char zSelName[12]; /* Symbolic name of this SELECT use for debugging */
#endif
int addrOpenEphm[2]; /* OP_OpenEphem opcodes related to this select */
- u64 nSelectRow; /* Estimated number of result rows */
SrcList *pSrc; /* The FROM clause */
Expr *pWhere; /* The WHERE clause */
ExprList *pGroupBy; /* The GROUP BY clause */
@@ -2531,22 +2552,23 @@ struct Select {
** Allowed values for Select.selFlags. The "SF" prefix stands for
** "Select Flag".
*/
-#define SF_Distinct 0x0001 /* Output should be DISTINCT */
-#define SF_All 0x0002 /* Includes the ALL keyword */
-#define SF_Resolved 0x0004 /* Identifiers have been resolved */
-#define SF_Aggregate 0x0008 /* Contains aggregate functions */
-#define SF_UsesEphemeral 0x0010 /* Uses the OpenEphemeral opcode */
-#define SF_Expanded 0x0020 /* sqlite3SelectExpand() called on this */
-#define SF_HasTypeInfo 0x0040 /* FROM subqueries have Table metadata */
-#define SF_Compound 0x0080 /* Part of a compound query */
-#define SF_Values 0x0100 /* Synthesized from VALUES clause */
-#define SF_MultiValue 0x0200 /* Single VALUES term with multiple rows */
-#define SF_NestedFrom 0x0400 /* Part of a parenthesized FROM clause */
-#define SF_MaybeConvert 0x0800 /* Need convertCompoundSelectToSubquery() */
-#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
-#define SF_Recursive 0x2000 /* The recursive part of a recursive CTE */
-#define SF_Converted 0x4000 /* By convertCompoundSelectToSubquery() */
-#define SF_IncludeHidden 0x8000 /* Include hidden columns in output */
+#define SF_Distinct 0x00001 /* Output should be DISTINCT */
+#define SF_All 0x00002 /* Includes the ALL keyword */
+#define SF_Resolved 0x00004 /* Identifiers have been resolved */
+#define SF_Aggregate 0x00008 /* Contains aggregate functions */
+#define SF_UsesEphemeral 0x00010 /* Uses the OpenEphemeral opcode */
+#define SF_Expanded 0x00020 /* sqlite3SelectExpand() called on this */
+#define SF_HasTypeInfo 0x00040 /* FROM subqueries have Table metadata */
+#define SF_Compound 0x00080 /* Part of a compound query */
+#define SF_Values 0x00100 /* Synthesized from VALUES clause */
+#define SF_MultiValue 0x00200 /* Single VALUES term with multiple rows */
+#define SF_NestedFrom 0x00400 /* Part of a parenthesized FROM clause */
+#define SF_MaybeConvert 0x00800 /* Need convertCompoundSelectToSubquery() */
+#define SF_MinMaxAgg 0x01000 /* Aggregate containing min() or max() */
+#define SF_Recursive 0x02000 /* The recursive part of a recursive CTE */
+#define SF_FixedLimit 0x04000 /* nSelectRow set by a constant LIMIT */
+#define SF_Converted 0x08000 /* By convertCompoundSelectToSubquery() */
+#define SF_IncludeHidden 0x10000 /* Include hidden columns in output */
/*
@@ -2554,7 +2576,7 @@ struct Select {
** by one of the following macros. The "SRT" prefix means "SELECT Result
** Type".
**
-** SRT_Union Store results as a key in a temporary index
+** SRT_Union Store results as a key in a temporary index
** identified by pDest->iSDParm.
**
** SRT_Except Remove results from the temporary index pDest->iSDParm.
@@ -2578,7 +2600,7 @@ struct Select {
** of the query. This destination implies "LIMIT 1".
**
** SRT_Set The result must be a single column. Store each
-** row of result as the key in table pDest->iSDParm.
+** row of result as the key in table pDest->iSDParm.
** Apply the affinity pDest->affSdst before storing
** results. Used to implement "IN (SELECT ...)".
**
@@ -2646,7 +2668,7 @@ struct SelectDest {
};
/*
-** During code generation of statements that do inserts into AUTOINCREMENT
+** During code generation of statements that do inserts into AUTOINCREMENT
** tables, the following information is attached to the Table.u.autoInc.p
** pointer of each autoincrement table to record some side information that
** the code generator needs. We have to keep per-table autoincrement
@@ -2669,7 +2691,7 @@ struct AutoincInfo {
#endif
/*
-** At least one instance of the following structure is created for each
+** At least one instance of the following structure is created for each
** trigger that may be fired while parsing an INSERT, UPDATE or DELETE
** statement. All such objects are stored in the linked list headed at
** Parse.pTriggerPrg and deleted once statement compilation has been
@@ -2682,7 +2704,7 @@ struct AutoincInfo {
** values for both pTrigger and orconf.
**
** The TriggerPrg.aColmask[0] variable is set to a mask of old.* columns
-** accessed (or set to 0 for triggers fired as a result of INSERT
+** accessed (or set to 0 for triggers fired as a result of INSERT
** statements). Similarly, the TriggerPrg.aColmask[1] variable is set to
** a mask of new.* columns used by the program.
*/
@@ -2723,7 +2745,7 @@ struct TriggerPrg {
** is constant but the second part is reset at the beginning and end of
** each recursion.
**
-** The nTableLock and aTableLock variables are only used if the shared-cache
+** The nTableLock and aTableLock variables are only used if the shared-cache
** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are
** used to store the set of table-locks required by the statement being
** compiled. Function sqlite3TableLock() is used to add entries to the
@@ -2880,10 +2902,10 @@ struct AuthContext {
/*
* Each trigger present in the database schema is stored as an instance of
- * struct Trigger.
+ * struct Trigger.
*
* Pointers to instances of struct Trigger are stored in two ways.
- * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
+ * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
* database). This allows Trigger structures to be retrieved by name.
* 2. All triggers associated with a single table form a linked list, using the
* pNext member of struct Trigger. A pointer to the first element of the
@@ -2909,7 +2931,7 @@ struct Trigger {
/*
** A trigger is either a BEFORE or an AFTER trigger. The following constants
-** determine which.
+** determine which.
**
** If there are multiple triggers, you might of some BEFORE and some AFTER.
** In that cases, the constants below can be ORed together.
@@ -2919,15 +2941,15 @@ struct Trigger {
/*
* An instance of struct TriggerStep is used to store a single SQL statement
- * that is a part of a trigger-program.
+ * that is a part of a trigger-program.
*
* Instances of struct TriggerStep are stored in a singly linked list (linked
- * using the "pNext" member) referenced by the "step_list" member of the
+ * using the "pNext" member) referenced by the "step_list" member of the
* associated struct Trigger instance. The first element of the linked list is
* the first step of the trigger-program.
- *
+ *
* The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
- * "SELECT" statement. The meanings of the other members is determined by the
+ * "SELECT" statement. The meanings of the other members is determined by the
* value of "op" as follows:
*
* (op == TK_INSERT)
@@ -2937,7 +2959,7 @@ struct Trigger {
* zTarget -> Dequoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
- * pIdList -> If this is an INSERT INTO ... () VALUES ...
+ * pIdList -> If this is an INSERT INTO ... () VALUES ...
* statement, then this stores the column-names to be
* inserted into.
*
@@ -2945,7 +2967,7 @@ struct Trigger {
* zTarget -> Dequoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
- *
+ *
* (op == TK_UPDATE)
* zTarget -> Dequoted name of the table to update.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
@@ -2953,7 +2975,7 @@ struct Trigger {
* pExprList -> A list of the columns to update and the expressions to update
* them to. See sqlite3Update() documentation of "pChanges"
* argument.
- *
+ *
*/
struct TriggerStep {
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
@@ -2971,7 +2993,7 @@ struct TriggerStep {
/*
** The following structure contains information used by the sqliteFix...
** routines as they walk the parse tree to make database references
-** explicit.
+** explicit.
*/
typedef struct DbFixer DbFixer;
struct DbFixer {
@@ -3181,6 +3203,15 @@ int sqlite3CantopenError(int);
#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
+#ifdef SQLITE_DEBUG
+ int sqlite3NomemError(int);
+ int sqlite3IoerrnomemError(int);
+# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__)
+# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__)
+#else
+# define SQLITE_NOMEM_BKPT SQLITE_NOMEM
+# define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM
+#endif
/*
** FTS3 and FTS4 both require virtual table support
@@ -3237,7 +3268,7 @@ int sqlite3IsIdChar(u8);
/*
** Internal function prototypes
*/
-#define sqlite3StrICmp sqlite3_stricmp
+int sqlite3StrICmp(const char*,const char*);
int sqlite3Strlen30(const char*);
#define sqlite3StrNICmp sqlite3_strnicmp
@@ -3277,7 +3308,7 @@ int sqlite3HeapNearlyFull(void);
#ifdef SQLITE_USE_ALLOCA
# define sqlite3StackAllocRaw(D,N) alloca(N)
# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N)
-# define sqlite3StackFree(D,P)
+# define sqlite3StackFree(D,P)
#else
# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N)
# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N)
@@ -3472,7 +3503,7 @@ Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
void sqlite3DropIndex(Parse*, SrcList*, int);
int sqlite3Select(Parse*, Select*, SelectDest*);
Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
- Expr*,ExprList*,u16,Expr*,Expr*);
+ Expr*,ExprList*,u32,Expr*,Expr*);
void sqlite3SelectDelete(sqlite3*, Select*);
Table *sqlite3SrcListLookup(Parse*, SrcList*);
int sqlite3IsReadOnly(Parse*, Table*, int);
@@ -3484,7 +3515,7 @@ void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
void sqlite3WhereEnd(WhereInfo*);
-u64 sqlite3WhereOutputRowCount(WhereInfo*);
+LogEst sqlite3WhereOutputRowCount(WhereInfo*);
int sqlite3WhereIsDistinct(WhereInfo*);
int sqlite3WhereIsOrdered(WhereInfo*);
int sqlite3WhereIsSorted(WhereInfo*);
@@ -3584,11 +3615,11 @@ void sqlite3SelectSetName(Select*,const char*);
#else
# define sqlite3SelectSetName(A,B)
#endif
-void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
-FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
-void sqlite3RegisterBuiltinFunctions(sqlite3*);
+void sqlite3InsertBuiltinFuncs(FuncDef*,int);
+FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
+void sqlite3RegisterBuiltinFunctions(void);
void sqlite3RegisterDateTimeFunctions(void);
-void sqlite3RegisterGlobalFunctions(void);
+void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
int sqlite3SafetyCheckOk(sqlite3*);
int sqlite3SafetyCheckSickOrOk(sqlite3*);
void sqlite3ChangeCookie(Parse*, int);
@@ -3734,7 +3765,7 @@ u8 sqlite3GetBoolean(const char *z,u8);
const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
-void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
+void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
void sqlite3ValueSetNull(sqlite3_value*);
void sqlite3ValueFree(sqlite3_value*);
@@ -3749,7 +3780,7 @@ extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char sqlite3CtypeMap[];
extern const Token sqlite3IntTokens[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
-extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
+extern FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
@@ -3794,7 +3825,7 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);
#ifdef SQLITE_DEBUG
int sqlite3KeyInfoIsWriteable(KeyInfo*);
#endif
-int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
+int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
void (*)(sqlite3_context*,int,sqlite3_value **),
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
FuncDestructor *pDestructor
@@ -3857,7 +3888,7 @@ void sqlite3AutoLoadExtensions(sqlite3*);
# define sqlite3VtabRollback(X)
# define sqlite3VtabCommit(X)
# define sqlite3VtabInSync(db) 0
-# define sqlite3VtabLock(X)
+# define sqlite3VtabLock(X)
# define sqlite3VtabUnlock(X)
# define sqlite3VtabUnlockList(X)
# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
@@ -3915,7 +3946,7 @@ const char *sqlite3JournalModename(int);
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
** key functionality is available. If OMIT_TRIGGER is defined but
** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In
-** this case foreign keys are parsed, but no other functionality is
+** this case foreign keys are parsed, but no other functionality is
** provided (enforcement of FK constraints requires the triggers sub-system).
*/
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
@@ -4019,7 +4050,7 @@ void sqlite3Put4byte(u8*, u32);
/*
** If the SQLITE_ENABLE IOTRACE exists then the global variable
** sqlite3IoTrace is a pointer to a printf-like routine used to
-** print I/O tracing messages.
+** print I/O tracing messages.
*/
#ifdef SQLITE_ENABLE_IOTRACE
# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; }
@@ -4053,7 +4084,7 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
** that allocations that might have been satisfied by lookaside are not
** passed back to non-lookaside free() routines. Asserts such as the
** example above are placed on the non-lookaside free() routines to verify
-** this constraint.
+** this constraint.
**
** All of this is no-op for a production build. It only comes into
** play when the SQLITE_MEMDEBUG compile-time option is used.
diff --git a/src/table.c b/src/table.c
index 153bfb319f..a50d83ce63 100644
--- a/src/table.c
+++ b/src/table.c
@@ -101,7 +101,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
return 0;
malloc_failed:
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
return 1;
}
@@ -142,7 +142,7 @@ int sqlite3_get_table(
res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
if( res.azResult==0 ){
db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
res.azResult[0] = 0;
rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
@@ -171,7 +171,7 @@ int sqlite3_get_table(
if( azNew==0 ){
sqlite3_free_table(&res.azResult[1]);
db->errCode = SQLITE_NOMEM;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
res.azResult = azNew;
}
diff --git a/src/test1.c b/src/test1.c
index c5e71582bc..713152b824 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -3154,7 +3154,7 @@ static int test_bind_zeroblob64(
){
sqlite3_stmt *pStmt;
int idx;
- i64 n;
+ Tcl_WideInt n;
int rc;
if( objc!=4 ){
diff --git a/src/test_blob.c b/src/test_blob.c
index 4a7075a28a..ec2227bb39 100644
--- a/src/test_blob.c
+++ b/src/test_blob.c
@@ -105,7 +105,7 @@ static int test_blob_open(
const char *zDb;
const char *zTable;
const char *zColumn;
- sqlite_int64 iRowid;
+ Tcl_WideInt iRowid;
int flags;
const char *zVarname;
int nVarname;
diff --git a/src/test_fs.c b/src/test_fs.c
index 45db0b53b8..32026d0f38 100644
--- a/src/test_fs.c
+++ b/src/test_fs.c
@@ -496,9 +496,9 @@ static int fstreeFilter(
#if SQLITE_OS_WIN
zRoot = sqlite3_mprintf("%s%c", getenv("SystemDrive"), '/');
- nRoot = strlen(zRoot);
+ nRoot = sqlite3Strlen30(zRoot);
zPrefix = sqlite3_mprintf("%s", getenv("SystemDrive"));
- nPrefix = strlen(zPrefix);
+ nPrefix = sqlite3Strlen30(zPrefix);
#else
zRoot = "/";
nRoot = 1;
diff --git a/src/threads.c b/src/threads.c
index 251b9b7631..f128d69fc2 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -63,7 +63,7 @@ int sqlite3ThreadCreate(
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
memset(p, 0, sizeof(*p));
p->xTask = xTask;
p->pIn = pIn;
@@ -89,7 +89,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
int rc;
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->done ){
*ppOut = p->pOut;
rc = SQLITE_OK;
@@ -154,7 +154,7 @@ int sqlite3ThreadCreate(
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
/* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a
** function that returns SQLITE_ERROR when passed the argument 200, that
** forces worker threads to run sequentially and deterministically
@@ -186,7 +186,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
BOOL bRc;
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->xTask==0 ){
/* assert( p->id==GetCurrentThreadId() ); */
rc = WAIT_OBJECT_0;
@@ -234,7 +234,7 @@ int sqlite3ThreadCreate(
assert( xTask!=0 );
*ppThread = 0;
p = sqlite3Malloc(sizeof(*p));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
p->xTask = xTask;
p->pIn = pIn;
@@ -250,7 +250,7 @@ int sqlite3ThreadCreate(
int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
assert( ppOut!=0 );
- if( NEVER(p==0) ) return SQLITE_NOMEM;
+ if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT;
if( p->xTask ){
*ppOut = p->xTask(p->pIn);
}else{
@@ -261,7 +261,7 @@ int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
#if defined(SQLITE_TEST)
{
void *pTstAlloc = sqlite3Malloc(10);
- if (!pTstAlloc) return SQLITE_NOMEM;
+ if (!pTstAlloc) return SQLITE_NOMEM_BKPT;
sqlite3_free(pTstAlloc);
}
#endif
diff --git a/src/tokenize.c b/src/tokenize.c
index 9b3444ac82..19a5ddf04d 100644
--- a/src/tokenize.c
+++ b/src/tokenize.c
@@ -285,7 +285,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
case CC_BANG: {
if( z[1]!='=' ){
*tokenType = TK_ILLEGAL;
- return 2;
+ return 1;
}else{
*tokenType = TK_NE;
return 2;
@@ -435,8 +435,8 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
*tokenType = TK_ID;
return keywordCode((char*)z, i, tokenType);
}
-#ifndef SQLITE_OMIT_BLOB_LITERAL
case CC_X: {
+#ifndef SQLITE_OMIT_BLOB_LITERAL
testcase( z[0]=='x' ); testcase( z[0]=='X' );
if( z[1]=='\'' ){
*tokenType = TK_BLOB;
@@ -448,10 +448,10 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){
if( z[i] ) i++;
return i;
}
+#endif
/* If it is not a BLOB literal, then it must be an ID, since no
** SQL keywords start with the letter 'x'. Fall through */
}
-#endif
case CC_ID: {
i = 1;
break;
@@ -495,7 +495,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
pEngine = sqlite3ParserAlloc(sqlite3Malloc);
if( pEngine==0 ){
sqlite3OomFault(db);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
@@ -523,18 +523,17 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
break;
}
}else{
- if( tokenType==TK_SEMI ) pParse->zTail = &zSql[i];
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
assert( nErr==0 );
+ pParse->zTail = &zSql[i];
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
assert( zSql[i]==0 );
if( lastTokenParsed!=TK_SEMI ){
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
- pParse->zTail = &zSql[i];
}
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
@@ -549,7 +548,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
#endif /* YYDEBUG */
sqlite3ParserFree(pEngine, sqlite3_free);
if( db->mallocFailed ){
- pParse->rc = SQLITE_NOMEM;
+ pParse->rc = SQLITE_NOMEM_BKPT;
}
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
diff --git a/src/treeview.c b/src/treeview.c
index 2985804314..ff3b4be5aa 100644
--- a/src/treeview.c
+++ b/src/treeview.c
@@ -132,9 +132,10 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
sqlite3TreeViewPush(pView, 1);
}
do{
- sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
+ sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
- ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
+ (int)p->nSelectRow
);
if( cnt++ ) sqlite3TreeViewPop(pView);
if( p->pPrior ){
diff --git a/src/utf.c b/src/utf.c
index e42ab418ad..7801306cb4 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -231,7 +231,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
rc = sqlite3VdbeMemMakeWriteable(pMem);
if( rc!=SQLITE_OK ){
assert( rc==SQLITE_NOMEM );
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
zIn = (u8*)pMem->z;
zTerm = &zIn[pMem->n&~1];
@@ -273,7 +273,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
zTerm = &zIn[pMem->n];
zOut = sqlite3DbMallocRaw(pMem->db, len);
if( !zOut ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
z = zOut;
diff --git a/src/util.c b/src/util.c
index 37b585b2ea..e325a7311b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -256,16 +256,25 @@ void sqlite3TokenInit(Token *p, char *z){
** independence" that SQLite uses internally when comparing identifiers.
*/
int sqlite3_stricmp(const char *zLeft, const char *zRight){
- register unsigned char *a, *b;
if( zLeft==0 ){
return zRight ? -1 : 0;
}else if( zRight==0 ){
return 1;
}
+ return sqlite3StrICmp(zLeft, zRight);
+}
+int sqlite3StrICmp(const char *zLeft, const char *zRight){
+ unsigned char *a, *b;
+ int c;
a = (unsigned char *)zLeft;
b = (unsigned char *)zRight;
- while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
- return UpperToLower[*a] - UpperToLower[*b];
+ for(;;){
+ c = (int)UpperToLower[*a] - (int)UpperToLower[*b];
+ if( c || *a==0 ) break;
+ a++;
+ b++;
+ }
+ return c;
}
int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
register unsigned char *a, *b;
@@ -1107,10 +1116,12 @@ u32 sqlite3Get4byte(const u8 *p){
void sqlite3Put4byte(unsigned char *p, u32 v){
#if SQLITE_BYTEORDER==4321
memcpy(p,&v,4);
-#elif SQLITE_BYTEORDER==1234 && defined(__GNUC__) && GCC_VERSION>=4003000
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(__GNUC__) && GCC_VERSION>=4003000
u32 x = __builtin_bswap32(v);
memcpy(p,&x,4);
-#elif SQLITE_BYTEORDER==1234 && defined(_MSC_VER) && _MSC_VER>=1300
+#elif SQLITE_BYTEORDER==1234 && !defined(SQLITE_DISABLE_INTRINSIC) \
+ && defined(_MSC_VER) && _MSC_VER>=1300
u32 x = _byteswap_ulong(v);
memcpy(p,&x,4);
#else
diff --git a/src/vacuum.c b/src/vacuum.c
index adc802e60b..bc7b5831b6 100644
--- a/src/vacuum.c
+++ b/src/vacuum.c
@@ -38,7 +38,7 @@ static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
sqlite3_stmt *pStmt;
VVA_ONLY( int rc; )
if( !zSql ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
@@ -219,7 +219,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
|| (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
|| NEVER(db->mallocFailed)
){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto end_of_vacuum;
}
diff --git a/src/vdbe.c b/src/vdbe.c
index cab0298348..7a47ef8b89 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -637,7 +637,11 @@ int sqlite3VdbeExec(
}
sqlite3EndBenignMalloc();
#endif
- for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+ for(pOp=&aOp[p->pc]; 1; pOp++){
+ /* Errors are detected by individual opcodes, with an immediate
+ ** jumps to abort_due_to_error. */
+ assert( rc==SQLITE_OK );
+
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
@@ -784,7 +788,7 @@ check_for_interrupt:
nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
if( db->xProgress(db->pProgressArg) ){
rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
+ goto abort_due_to_error;
}
}
#endif
@@ -1063,7 +1067,10 @@ case OP_String8: { /* same as TK_STRING, out2 */
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
- if( rc==SQLITE_TOOBIG ) goto too_big;
+ if( rc ){
+ assert( rc==SQLITE_TOOBIG ); /* This is the only possible error here */
+ goto too_big;
+ }
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
assert( VdbeMemDynamic(pOut)==0 );
@@ -1329,7 +1336,7 @@ case OP_ResultRow: {
&& db->xProgress(db->pProgressArg)!=0
){
rc = SQLITE_INTERRUPT;
- goto vdbe_error_halt;
+ goto abort_due_to_error;
}
#endif
@@ -1339,7 +1346,7 @@ case OP_ResultRow: {
if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
assert( db->flags&SQLITE_CountRows );
assert( p->usesStmtJournal );
- break;
+ goto abort_due_to_error;
}
/* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
@@ -1359,9 +1366,7 @@ case OP_ResultRow: {
*/
assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
- if( NEVER(rc!=SQLITE_OK) ){
- break;
- }
+ assert( rc==SQLITE_OK );
/* Invalidate all ephemeral cursor row caches */
p->cacheCtr = (p->cacheCtr + 2)|1;
@@ -1684,7 +1689,8 @@ case OP_Function: {
sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
rc = pCtx->isError;
}
- sqlite3VdbeDeleteAuxData(p, pCtx->iOp, pOp->p1);
+ sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
+ if( rc ) goto abort_due_to_error;
}
/* Copy the result of the function into register P3 */
@@ -1868,6 +1874,7 @@ case OP_Cast: { /* in1 */
rc = ExpandBlob(pIn1);
sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
UPDATE_MAX_BLOBSIZE(pIn1);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_CAST */
@@ -2477,7 +2484,7 @@ case OP_Column: {
*/
if( offset > 98307 || offset > pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
- goto op_column_error;
+ goto abort_due_to_error;
}
}
@@ -2502,7 +2509,7 @@ case OP_Column: {
if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem));
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
- if( rc!=SQLITE_OK ) goto op_column_error;
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
zData = pC->aRow;
@@ -2538,7 +2545,7 @@ case OP_Column: {
|| (offset64 > pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
- goto op_column_error;
+ goto abort_due_to_error;
}
}else{
t = 0;
@@ -2611,15 +2618,13 @@ case OP_Column: {
}else{
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
pDest);
- if( rc==SQLITE_OK ){
- sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
- pDest->flags &= ~MEM_Ephem;
- }
+ if( rc!=SQLITE_OK ) goto abort_due_to_error;
+ sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
+ pDest->flags &= ~MEM_Ephem;
}
}
op_column_out:
-op_column_error:
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
@@ -2824,6 +2829,7 @@ case OP_Count: { /* out2 */
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ if( rc ) goto abort_due_to_error;
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
@@ -3001,6 +3007,7 @@ case OP_Savepoint: {
}
}
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3037,7 +3044,7 @@ case OP_AutoCommit: {
sqlite3VdbeError(p, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- break;
+ goto abort_due_to_error;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
@@ -3064,6 +3071,7 @@ case OP_AutoCommit: {
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
+ goto abort_due_to_error;
}
break;
}
@@ -3186,6 +3194,7 @@ case OP_Transaction: {
p->expired = 1;
rc = SQLITE_SCHEMA;
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3255,6 +3264,7 @@ case OP_SetCookie: {
sqlite3ExpirePreparedStatements(db);
p->expired = 0;
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3352,7 +3362,7 @@ case OP_OpenWrite:
if( p->expired ){
rc = SQLITE_ABORT_ROLLBACK;
- break;
+ goto abort_due_to_error;
}
nField = 0;
@@ -3386,10 +3396,7 @@ case OP_OpenWrite:
** that opcode will always set the p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
- if( NEVER(p2<2) ) {
- rc = SQLITE_CORRUPT_BKPT;
- goto abort_due_to_error;
- }
+ assert( p2>=2 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;
@@ -3427,6 +3434,7 @@ open_cursor_set_hints:
#endif
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3503,6 +3511,7 @@ case OP_OpenEphemeral: {
pCx->isTable = 1;
}
}
+ if( rc ) goto abort_due_to_error;
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
@@ -3528,6 +3537,7 @@ case OP_SorterOpen: {
assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) );
rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -3990,7 +4000,7 @@ case OP_Found: { /* jump, in3 */
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
- break;
+ goto abort_due_to_error;
}
pC->seekResult = res;
alreadyExists = (res==0);
@@ -4062,6 +4072,7 @@ case OP_NotExists: { /* jump, in3 */
goto jump_to_p2;
}
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -4204,7 +4215,8 @@ case OP_NewRowid: { /* out2 */
0, &res))==SQLITE_OK)
&& (res==0)
&& (++cnt<100));
- if( rc==SQLITE_OK && res==0 ){
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
goto abort_due_to_error;
}
@@ -4338,7 +4350,8 @@ case OP_InsertInt: {
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && op && HasRowid(pTab) ){
+ if( rc ) goto abort_due_to_error;
+ if( db->xUpdateCallback && op && HasRowid(pTab) ){
db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, iKey);
}
break;
@@ -4453,6 +4466,7 @@ case OP_Delete: {
rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
pC->cacheStatus = CACHE_STALE;
+ if( rc ) goto abort_due_to_error;
/* Invoke the update-hook if required. */
if( opflags & OPFLAG_NCHANGE ){
@@ -4507,6 +4521,7 @@ case OP_SorterCompare: {
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
+ if( rc ) goto abort_due_to_error;
if( res ) goto jump_to_p2;
break;
};
@@ -4532,6 +4547,7 @@ case OP_SorterData: {
rc = sqlite3VdbeSorterRowkey(pC, pOut);
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
assert( pOp->p1>=0 && pOp->p1nCursor );
+ if( rc ) goto abort_due_to_error;
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
@@ -4620,6 +4636,7 @@ case OP_RowData: {
}else{
rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
}
+ if( rc ) goto abort_due_to_error;
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
@@ -4660,6 +4677,7 @@ case OP_Rowid: { /* out2 */
assert( pModule->xRowid );
rc = pModule->xRowid(pC->uc.pVCur, &v);
sqlite3VtabImportErrmsg(p, pVtab);
+ if( rc ) goto abort_due_to_error;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
assert( pC->eCurType==CURTYPE_BTREE );
@@ -4730,6 +4748,7 @@ case OP_Last: { /* jump */
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
+ if( rc ) goto abort_due_to_error;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@@ -4794,6 +4813,7 @@ case OP_Rewind: { /* jump */
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
+ if( rc ) goto abort_due_to_error;
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2nOp );
VdbeBranchTaken(res!=0,2);
@@ -4906,6 +4926,7 @@ case OP_Next: /* jump */
next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
+ if( rc ) goto abort_due_to_error;
if( res==0 ){
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
@@ -4956,19 +4977,19 @@ case OP_IdxInsert: { /* in2 */
assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
- if( rc==SQLITE_OK ){
- if( pOp->opcode==OP_SorterInsert ){
- rc = sqlite3VdbeSorterWrite(pC, pIn2);
- }else{
- nKey = pIn2->n;
- zKey = pIn2->z;
- rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
- );
- assert( pC->deferredMoveto==0 );
- pC->cacheStatus = CACHE_STALE;
- }
+ if( rc ) goto abort_due_to_error;
+ if( pOp->opcode==OP_SorterInsert ){
+ rc = sqlite3VdbeSorterWrite(pC, pIn2);
+ }else{
+ nKey = pIn2->n;
+ zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
+ );
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
}
+ if( rc) goto abort_due_to_error;
break;
}
@@ -4999,8 +5020,10 @@ case OP_IdxDelete: {
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
- if( rc==SQLITE_OK && res==0 ){
+ if( rc ) goto abort_due_to_error;
+ if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
+ if( rc ) goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
@@ -5175,6 +5198,7 @@ case OP_IdxGE: { /* jump */
res++;
}
VdbeBranchTaken(res>0,2);
+ if( rc ) goto abort_due_to_error;
if( res>0 ) goto jump_to_p2;
break;
}
@@ -5210,6 +5234,7 @@ case OP_Destroy: { /* out2 */
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
+ goto abort_due_to_error;
}else{
iDb = pOp->p3;
assert( DbMaskTest(p->btreeMask, iDb) );
@@ -5217,8 +5242,9 @@ case OP_Destroy: { /* out2 */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int;
pOut->u.i = iMoved;
+ if( rc ) goto abort_due_to_error;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && iMoved!=0 ){
+ if( iMoved!=0 ){
sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
/* All OP_Destroy operations occur on the same btree */
assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
@@ -5264,6 +5290,7 @@ case OP_Clear: {
aMem[pOp->p3].u.i += nChange;
}
}
+ if( rc ) goto abort_due_to_error;
break;
}
@@ -5287,6 +5314,7 @@ case OP_ResetSorter: {
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->isEphemeral );
rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
+ if( rc ) goto abort_due_to_error;
}
break;
}
@@ -5335,6 +5363,7 @@ case OP_CreateTable: { /* out2 */
flags = BTREE_BLOBKEY;
}
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+ if( rc ) goto abort_due_to_error;
pOut->u.i = pgno;
break;
}
@@ -5375,7 +5404,7 @@ case OP_ParseSchema: {
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zName, zMaster, pOp->p4.z);
if( zSql==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
@@ -5387,9 +5416,12 @@ case OP_ParseSchema: {
db->init.busy = 0;
}
}
- if( rc ) sqlite3ResetAllSchemasOfConnection(db);
- if( rc==SQLITE_NOMEM ){
- goto no_mem;
+ if( rc ){
+ sqlite3ResetAllSchemasOfConnection(db);
+ if( rc==SQLITE_NOMEM ){
+ goto no_mem;
+ }
+ goto abort_due_to_error;
}
break;
}
@@ -5404,6 +5436,7 @@ case OP_ParseSchema: {
case OP_LoadAnalysis: {
assert( pOp->p1>=0 && pOp->p1nDb );
rc = sqlite3AnalysisLoad(db, pOp->p1);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) */
@@ -5663,7 +5696,7 @@ case OP_Program: { /* jump */
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
sqlite3VdbeError(p, "too many levels of trigger recursion");
- break;
+ goto abort_due_to_error;
}
/* Register pRt is used to store the memory required to save the state
@@ -5723,6 +5756,9 @@ case OP_Program: { /* jump */
pFrame->lastRowid = lastRowid;
pFrame->nChange = p->nChange;
pFrame->nDbChange = p->db->nChange;
+ assert( pFrame->pAuxData==0 );
+ pFrame->pAuxData = p->pAuxData;
+ p->pAuxData = 0;
p->nChange = 0;
p->pFrame = pFrame;
p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
@@ -6027,6 +6063,7 @@ case OP_AggStep: {
rc = pCtx->isError;
}
sqlite3VdbeMemRelease(&t);
+ if( rc ) goto abort_due_to_error;
}else{
assert( t.flags==MEM_Null );
}
@@ -6059,6 +6096,7 @@ case OP_AggFinal: {
rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
+ goto abort_due_to_error;
}
sqlite3VdbeChangeEncoding(pMem, encoding);
UPDATE_MAX_BLOBSIZE(pMem);
@@ -6094,7 +6132,8 @@ case OP_Checkpoint: {
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
);
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
- if( rc==SQLITE_BUSY ){
+ if( rc ){
+ if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
rc = SQLITE_OK;
aRes[0] = 1;
}
@@ -6167,7 +6206,7 @@ case OP_JournalMode: { /* out2 */
"cannot change %s wal mode from within a transaction",
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
- break;
+ goto abort_due_to_error;
}else{
if( eOld==PAGER_JOURNALMODE_WAL ){
@@ -6197,9 +6236,7 @@ case OP_JournalMode: { /* out2 */
}
#endif /* ifndef SQLITE_OMIT_WAL */
- if( rc ){
- eNew = eOld;
- }
+ if( rc ) eNew = eOld;
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
@@ -6207,6 +6244,7 @@ case OP_JournalMode: { /* out2 */
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
+ if( rc ) goto abort_due_to_error;
break;
};
#endif /* SQLITE_OMIT_PRAGMA */
@@ -6221,6 +6259,7 @@ case OP_JournalMode: { /* out2 */
case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif
@@ -6241,7 +6280,8 @@ case OP_IncrVacuum: { /* jump */
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
- if( rc==SQLITE_DONE ){
+ if( rc ){
+ if( rc!=SQLITE_DONE ) goto abort_due_to_error;
rc = SQLITE_OK;
goto jump_to_p2;
}
@@ -6292,9 +6332,12 @@ case OP_TableLock: {
assert( DbMaskTest(p->btreeMask, p1) );
assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( (rc&0xFF)==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3VdbeError(p, "database table is locked: %s", z);
+ if( rc ){
+ if( (rc&0xFF)==SQLITE_LOCKED ){
+ const char *z = pOp->p4.z;
+ sqlite3VdbeError(p, "database table is locked: %s", z);
+ }
+ goto abort_due_to_error;
}
}
break;
@@ -6316,6 +6359,7 @@ case OP_VBegin: {
pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVTab);
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6344,6 +6388,7 @@ case OP_VCreate: {
rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
}
sqlite3VdbeMemRelease(&sMem);
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6358,6 +6403,7 @@ case OP_VDestroy: {
db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6381,25 +6427,25 @@ case OP_VOpen: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
- break;
+ goto abort_due_to_error;
}
pModule = pVtab->pModule;
rc = pModule->xOpen(pVtab, &pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
- if( SQLITE_OK==rc ){
- /* Initialize sqlite3_vtab_cursor base class */
- pVCur->pVtab = pVtab;
+ if( rc ) goto abort_due_to_error;
- /* Initialize vdbe cursor object */
- pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
- if( pCur ){
- pCur->uc.pVCur = pVCur;
- pVtab->nRef++;
- }else{
- assert( db->mallocFailed );
- pModule->xClose(pVCur);
- goto no_mem;
- }
+ /* Initialize sqlite3_vtab_cursor base class */
+ pVCur->pVtab = pVtab;
+
+ /* Initialize vdbe cursor object */
+ pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
+ if( pCur ){
+ pCur->uc.pVCur = pVCur;
+ pVtab->nRef++;
+ }else{
+ assert( db->mallocFailed );
+ pModule->xClose(pVCur);
+ goto no_mem;
}
break;
}
@@ -6461,9 +6507,8 @@ case OP_VFilter: { /* jump */
}
rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pVCur);
- }
+ if( rc ) goto abort_due_to_error;
+ res = pModule->xEof(pVCur);
pCur->nullRow = 0;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@@ -6512,6 +6557,7 @@ case OP_VColumn: {
if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
+ if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -6547,9 +6593,8 @@ case OP_VNext: { /* jump */
*/
rc = pModule->xNext(pCur->uc.pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
- if( rc==SQLITE_OK ){
- res = pModule->xEof(pCur->uc.pVCur);
- }
+ if( rc ) goto abort_due_to_error;
+ res = pModule->xEof(pCur->uc.pVCur);
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
@@ -6581,11 +6626,11 @@ case OP_VRename: {
testcase( pName->enc==SQLITE_UTF16BE );
testcase( pName->enc==SQLITE_UTF16LE );
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
- if( rc==SQLITE_OK ){
- rc = pVtab->pModule->xRename(pVtab, pName->z);
- sqlite3VtabImportErrmsg(p, pVtab);
- p->expired = 0;
- }
+ if( rc ) goto abort_due_to_error;
+ rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ p->expired = 0;
+ if( rc ) goto abort_due_to_error;
break;
}
#endif
@@ -6634,7 +6679,7 @@ case OP_VUpdate: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
- break;
+ goto abort_due_to_error;
}
pModule = pVtab->pModule;
nArg = pOp->p2;
@@ -6666,6 +6711,7 @@ case OP_VUpdate: {
}else{
p->nChange++;
}
+ if( rc ) goto abort_due_to_error;
}
break;
}
@@ -6837,8 +6883,12 @@ default: { /* This is really OP_Noop and OP_Explain */
/* If we reach this point, it means that execution is finished with
** an error of some kind.
*/
-vdbe_error_halt:
+abort_due_to_error:
+ if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
assert( rc );
+ if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
+ }
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
@@ -6869,34 +6919,23 @@ vdbe_return:
too_big:
sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
- goto vdbe_error_halt;
+ goto abort_due_to_error;
/* Jump to here if a malloc() fails.
*/
no_mem:
sqlite3OomFault(db);
sqlite3VdbeError(p, "out of memory");
- rc = SQLITE_NOMEM;
- goto vdbe_error_halt;
-
- /* Jump to here for any other kind of fatal error. The "rc" variable
- ** should hold the error number.
- */
-abort_due_to_error:
- assert( p->zErrMsg==0 );
- if( db->mallocFailed ) rc = SQLITE_NOMEM;
- if( rc!=SQLITE_IOERR_NOMEM ){
- sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
- }
- goto vdbe_error_halt;
+ rc = SQLITE_NOMEM_BKPT;
+ goto abort_due_to_error;
/* Jump to here if the sqlite3_interrupt() API sets the interrupt
** flag.
*/
abort_due_to_interrupt:
assert( db->u1.isInterrupted );
- rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_INTERRUPT;
+ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
p->rc = rc;
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
- goto vdbe_error_halt;
+ goto abort_due_to_error;
}
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index fada20370a..4dab3ba49e 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -161,6 +161,7 @@ struct VdbeFrame {
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
void *token; /* Copy of SubProgram.token */
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
+ AuxData *pAuxData; /* Linked list of auxdata allocations */
int nCursor; /* Number of entries in apCsr */
int pc; /* Program Counter in parent (calling) frame */
int nOp; /* Size of aOp array */
@@ -462,7 +463,7 @@ u8 sqlite3VdbeOneByteSerialTypeLen(u8);
u32 sqlite3VdbeSerialType(Mem*, int, u32*);
u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
-void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
+void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index be70c67196..1feecb3e11 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -471,7 +471,7 @@ void sqlite3_result_error_toobig(sqlite3_context *pCtx){
void sqlite3_result_error_nomem(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
- pCtx->isError = SQLITE_NOMEM;
+ pCtx->isError = SQLITE_NOMEM_BKPT;
pCtx->fErrorOrAux = 1;
sqlite3OomFault(pCtx->pOut->db);
}
@@ -547,7 +547,7 @@ static int sqlite3Step(Vdbe *p){
db = p->db;
if( db->mallocFailed ){
p->rc = SQLITE_NOMEM;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
if( p->pc<=0 && p->expired ){
@@ -610,7 +610,7 @@ static int sqlite3Step(Vdbe *p){
db->errCode = rc;
if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
}
end_of_step:
/* At this point local variable rc holds the value that should be
@@ -677,7 +677,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
v->rc = rc2;
} else {
v->zErrMsg = 0;
- v->rc = rc = SQLITE_NOMEM;
+ v->rc = rc = SQLITE_NOMEM_BKPT;
}
}
rc = sqlite3ApiExit(db, rc);
@@ -1301,6 +1301,9 @@ int sqlite3_bind_blob(
int nData,
void (*xDel)(void*)
){
+#ifdef SQLITE_ENABLE_API_ARMOR
+ if( nData<0 ) return SQLITE_MISUSE_BKPT;
+#endif
return bindText(pStmt, i, zData, nData, xDel, 0);
}
int sqlite3_bind_blob64(
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 5545e8785c..50f5e99c50 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -130,7 +130,7 @@ static int growOpArray(Vdbe *v, int nOp){
p->nOpAlloc = p->szOpAlloc/sizeof(Op);
v->aOp = pNew;
}
- return (pNew ? SQLITE_OK : SQLITE_NOMEM);
+ return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
}
#ifdef SQLITE_DEBUG
@@ -1489,6 +1489,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){
sqlite3VdbeFreeCursor(p->v, apCsr[i]);
}
releaseMemArray(aMem, p->nChildMem);
+ sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
sqlite3DbFree(p->v->db, p);
}
@@ -1531,7 +1532,7 @@ int sqlite3VdbeList(
releaseMemArray(pMem, 8);
p->pResultSet = 0;
- if( p->rc==SQLITE_NOMEM ){
+ if( p->rc==SQLITE_NOMEM_BKPT ){
/* This happens if a malloc() inside a call to sqlite3_column_text() or
** sqlite3_column_text16() failed. */
sqlite3OomFault(db);
@@ -2017,6 +2018,9 @@ int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
v->db->lastRowid = pFrame->lastRowid;
v->nChange = pFrame->nChange;
v->db->nChange = pFrame->nDbChange;
+ sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0);
+ v->pAuxData = pFrame->pAuxData;
+ pFrame->pAuxData = 0;
return pFrame->pc;
}
@@ -2048,7 +2052,7 @@ static void closeAllCursors(Vdbe *p){
}
/* Delete any auxdata allocations made by the VM */
- if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
+ if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0);
assert( p->pAuxData==0 );
}
@@ -2120,7 +2124,7 @@ int sqlite3VdbeSetColName(
assert( vardb->mallocFailed ){
assert( !zName || xDel!=SQLITE_DYNAMIC );
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
assert( p->aColName!=0 );
pColName = &(p->aColName[idx+var*p->nResColumn]);
@@ -2137,7 +2141,9 @@ int sqlite3VdbeSetColName(
*/
static int vdbeCommit(sqlite3 *db, Vdbe *p){
int i;
- int nTrans = 0; /* Number of databases with an active write-transaction */
+ int nTrans = 0; /* Number of databases with an active write-transaction
+ ** that are candidates for a two-phase commit using a
+ ** master-journal */
int rc = SQLITE_OK;
int needXcommit = 0;
@@ -2165,10 +2171,28 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
for(i=0; rc==SQLITE_OK && inDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( sqlite3BtreeIsInTrans(pBt) ){
+ /* Whether or not a database might need a master journal depends upon
+ ** its journal mode (among other things). This matrix determines which
+ ** journal modes use a master journal and which do not */
+ static const u8 aMJNeeded[] = {
+ /* DELETE */ 1,
+ /* PERSIST */ 1,
+ /* OFF */ 0,
+ /* TRUNCATE */ 1,
+ /* MEMORY */ 0,
+ /* WAL */ 0
+ };
+ Pager *pPager; /* Pager associated with pBt */
needXcommit = 1;
- if( i!=1 ) nTrans++;
sqlite3BtreeEnter(pBt);
- rc = sqlite3PagerExclusiveLock(sqlite3BtreePager(pBt));
+ pPager = sqlite3BtreePager(pBt);
+ if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF
+ && aMJNeeded[sqlite3PagerGetJournalMode(pPager)]
+ ){
+ assert( i!=1 );
+ nTrans++;
+ }
+ rc = sqlite3PagerExclusiveLock(pPager);
sqlite3BtreeLeave(pBt);
}
}
@@ -2226,7 +2250,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
#ifndef SQLITE_OMIT_DISKIO
else{
sqlite3_vfs *pVfs = db->pVfs;
- int needSync = 0;
char *zMaster = 0; /* File-name for the master journal */
char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
sqlite3_file *pMaster = 0;
@@ -2238,7 +2261,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* Select a master journal file name */
nMainFile = sqlite3Strlen30(zMainFile);
zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
- if( zMaster==0 ) return SQLITE_NOMEM;
+ if( zMaster==0 ) return SQLITE_NOMEM_BKPT;
do {
u32 iRandom;
if( retryCount ){
@@ -2286,9 +2309,6 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
continue; /* Ignore TEMP and :memory: databases */
}
assert( zFile[0]!=0 );
- if( !needSync && !sqlite3BtreeSyncDisabled(pBt) ){
- needSync = 1;
- }
rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset);
offset += sqlite3Strlen30(zFile)+1;
if( rc!=SQLITE_OK ){
@@ -2303,8 +2323,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
/* Sync the master journal file. If the IOCAP_SEQUENTIAL device
** flag is set this is not required.
*/
- if( needSync
- && 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
+ if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL)
&& SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL))
){
sqlite3OsCloseFree(pMaster);
@@ -2340,7 +2359,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
** doing this the directory is synced again before any individual
** transaction files are deleted.
*/
- rc = sqlite3OsDelete(pVfs, zMaster, needSync);
+ rc = sqlite3OsDelete(pVfs, zMaster, 1);
sqlite3DbFree(db, zMaster);
zMaster = 0;
if( rc ){
@@ -2528,7 +2547,7 @@ int sqlite3VdbeHalt(Vdbe *p){
*/
if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
}
if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
closeAllCursors(p);
@@ -2689,7 +2708,7 @@ int sqlite3VdbeHalt(Vdbe *p){
p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(db);
if( db->mallocFailed ){
- p->rc = SQLITE_NOMEM;
+ p->rc = SQLITE_NOMEM_BKPT;
}
/* If the auto-commit flag is set to true, then any locks that were held
@@ -2876,8 +2895,7 @@ int sqlite3VdbeFinalize(Vdbe *p){
** * the corresponding bit in argument mask is clear (where the first
** function parameter corresponds to bit 0 etc.).
*/
-void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
- AuxData **pp = &pVdbe->pAuxData;
+void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
@@ -2888,7 +2906,7 @@ void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
pAux->xDelete(pAux->pAux);
}
*pp = pAux->pNext;
- sqlite3DbFree(pVdbe->db, pAux);
+ sqlite3DbFree(db, pAux);
}else{
pp= &pAux->pNext;
}
@@ -3668,7 +3686,7 @@ static int vdbeCompareMemString(
v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
n2 = v2==0 ? 0 : c2.n;
rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
- if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
+ if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM_BKPT;
sqlite3VdbeMemRelease(&c1);
sqlite3VdbeMemRelease(&c2);
return rc;
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 83b8feb34f..8930c76d4e 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -138,7 +138,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
sqlite3VdbeMemSetNull(pMem);
pMem->z = 0;
pMem->szMalloc = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}else{
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
}
@@ -196,7 +196,7 @@ int sqlite3VdbeMemMakeWriteable(Mem *pMem){
f = pMem->flags;
if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
@@ -228,7 +228,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
nByte = 1;
}
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
@@ -245,7 +245,7 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){
*/
static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pMem->z[pMem->n] = 0;
pMem->z[pMem->n+1] = 0;
@@ -294,7 +294,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
/* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
@@ -901,7 +901,7 @@ int sqlite3VdbeMemSetStr(
testcase( nAlloc==31 );
testcase( nAlloc==32 );
if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pMem->z, z, nAlloc);
}else if( xDel==SQLITE_DYNAMIC ){
@@ -921,7 +921,7 @@ int sqlite3VdbeMemSetStr(
#ifndef SQLITE_OMIT_UTF16
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
#endif
@@ -1182,7 +1182,6 @@ static int valueFromFunction(
FuncDef *pFunc = 0; /* Function definition */
sqlite3_value *pVal = 0; /* New value */
int rc = SQLITE_OK; /* Return code */
- int nName; /* Size of function name in bytes */
ExprList *pList = 0; /* Function arguments */
int i; /* Iterator variable */
@@ -1190,8 +1189,7 @@ static int valueFromFunction(
assert( (p->flags & EP_TokenOnly)==0 );
pList = p->x.pList;
if( pList ) nVal = pList->nExpr;
- nName = sqlite3Strlen30(p->u.zToken);
- pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
+ pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
assert( pFunc );
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -1202,7 +1200,7 @@ static int valueFromFunction(
if( pList ){
apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
if( apVal==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto value_from_function_out;
}
for(i=0; inRec ) return SQLITE_CORRUPT_BKPT;
if( pMem==0 ){
pMem = *ppVal = sqlite3ValueNew(db);
- if( pMem==0 ) return SQLITE_NOMEM;
+ if( pMem==0 ) return SQLITE_NOMEM_BKPT;
}
sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
pMem->enc = ENC(db);
diff --git a/src/vdbesort.c b/src/vdbesort.c
index 380772ee16..5913cda6d0 100644
--- a/src/vdbesort.c
+++ b/src/vdbesort.c
@@ -540,7 +540,7 @@ static int vdbePmaReadBlob(
int nNew = MAX(128, p->nAlloc*2);
while( nByte>nNew ) nNew = nNew*2;
aNew = sqlite3Realloc(p->aAlloc, nNew);
- if( !aNew ) return SQLITE_NOMEM;
+ if( !aNew ) return SQLITE_NOMEM_BKPT;
p->nAlloc = nNew;
p->aAlloc = aNew;
}
@@ -652,7 +652,7 @@ static int vdbePmaReaderSeek(
int iBuf = pReadr->iReadOff % pgsz;
if( pReadr->aBuffer==0 ){
pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
- if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
+ if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT;
pReadr->nBuffer = pgsz;
}
if( rc==SQLITE_OK && iBuf ){
@@ -968,7 +968,7 @@ int sqlite3VdbeSorterInit(
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
pCsr->uc.pSorter = pSorter;
if( pSorter==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
@@ -1002,7 +1002,7 @@ int sqlite3VdbeSorterInit(
assert( pSorter->iMemory==0 );
pSorter->nMemory = pgsz;
pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
- if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
+ if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT;
}
}
@@ -1324,7 +1324,7 @@ static int vdbeSortAllocUnpacked(SortSubtask *pTask){
pTask->pSorter->pKeyInfo, 0, 0, &pFree
);
assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
- if( pFree==0 ) return SQLITE_NOMEM;
+ if( pFree==0 ) return SQLITE_NOMEM_BKPT;
pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
pTask->pUnpacked->errCode = 0;
}
@@ -1399,7 +1399,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
if( !aSlot ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
while( p ){
@@ -1449,7 +1449,7 @@ static void vdbePmaWriterInit(
memset(p, 0, sizeof(PmaWriter));
p->aBuffer = (u8*)sqlite3Malloc(nBuf);
if( !p->aBuffer ){
- p->eFWErr = SQLITE_NOMEM;
+ p->eFWErr = SQLITE_NOMEM_BKPT;
}else{
p->iBufEnd = p->iBufStart = (iStart % nBuf);
p->iWriteOff = iStart - p->iBufStart;
@@ -1737,7 +1737,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
pSorter->nMemory = sqlite3MallocSize(aMem);
}else if( pSorter->list.aMemory ){
pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
- if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
+ if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT;
}
rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
@@ -1828,7 +1828,7 @@ int sqlite3VdbeSorterWrite(
if( nNew < nMin ) nNew = nMin;
aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
- if( !aNew ) return SQLITE_NOMEM;
+ if( !aNew ) return SQLITE_NOMEM_BKPT;
pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
pSorter->list.aMemory = aNew;
pSorter->nMemory = nNew;
@@ -1842,7 +1842,7 @@ int sqlite3VdbeSorterWrite(
}else{
pNew = (SorterRecord *)sqlite3Malloc(nReq);
if( pNew==0 ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pNew->u.pNext = pSorter->list.pList;
}
@@ -1989,7 +1989,7 @@ static int vdbeIncrMergerNew(
pTask->file2.iEof += pIncr->mxSz;
}else{
vdbeMergeEngineFree(pMerger);
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
return rc;
}
@@ -2294,10 +2294,10 @@ static int vdbeMergeEngineLevel0(
int rc = SQLITE_OK;
*ppOut = pNew = vdbeMergeEngineNew(nPMA);
- if( pNew==0 ) rc = SQLITE_NOMEM;
+ if( pNew==0 ) rc = SQLITE_NOMEM_BKPT;
for(i=0; iaReadr[i];
rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
iOff = pReadr->iEof;
@@ -2365,7 +2365,7 @@ static int vdbeSorterAddToTree(
if( pReadr->pIncr==0 ){
MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
if( pNew==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
}
@@ -2410,7 +2410,7 @@ static int vdbeSorterMergeTreeBuild(
assert( pSorter->bUseThreads || pSorter->nTask==1 );
if( pSorter->nTask>1 ){
pMain = vdbeMergeEngineNew(pSorter->nTask);
- if( pMain==0 ) rc = SQLITE_NOMEM;
+ if( pMain==0 ) rc = SQLITE_NOMEM_BKPT;
}
#endif
@@ -2428,7 +2428,7 @@ static int vdbeSorterMergeTreeBuild(
int i;
int iSeq = 0;
pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
- if( pRoot==0 ) rc = SQLITE_NOMEM;
+ if( pRoot==0 ) rc = SQLITE_NOMEM_BKPT;
for(i=0; inPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
MergeEngine *pMerger = 0; /* New level-0 PMA merger */
int nReader; /* Number of level-0 PMAs to merge */
@@ -2499,7 +2499,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
if( rc==SQLITE_OK ){
pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
pSorter->pReader = pReadr;
- if( pReadr==0 ) rc = SQLITE_NOMEM;
+ if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT;
}
if( rc==SQLITE_OK ){
rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
@@ -2676,7 +2676,7 @@ int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
pSorter = pCsr->uc.pSorter;
pKey = vdbeSorterRowkey(pSorter, &nKey);
if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pOut->n = nKey;
MemSetTypeFlag(pOut, MEM_Blob);
@@ -2721,7 +2721,7 @@ int sqlite3VdbeSorterCompare(
char *p;
r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
assert( pSorter->pUnpacked==(UnpackedRecord*)p );
- if( r2==0 ) return SQLITE_NOMEM;
+ if( r2==0 ) return SQLITE_NOMEM_BKPT;
r2->nField = nKeyCol;
}
assert( r2->nField==nKeyCol );
diff --git a/src/vtab.c b/src/vtab.c
index e8794e687d..fa19548199 100644
--- a/src/vtab.c
+++ b/src/vtab.c
@@ -506,13 +506,13 @@ static int vtabCallConstructor(
zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
if( !zModuleName ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pVTable = sqlite3DbMallocZero(db, sizeof(VTable));
if( !pVTable ){
sqlite3DbFree(db, zModuleName);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pVTable->db = db;
pVTable->pMod = pMod;
@@ -655,7 +655,7 @@ static int growVTrans(sqlite3 *db){
int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
if( !aVTrans ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
db->aVTrans = aVTrans;
@@ -747,7 +747,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
if( pParse==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
pParse->declareVtab = 1;
pParse->db = db;
@@ -1059,8 +1059,8 @@ FuncDef *sqlite3VtabOverloadFunction(
return pDef;
}
*pNew = *pDef;
- pNew->zName = (char *)&pNew[1];
- memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1);
+ pNew->zName = (const char*)&pNew[1];
+ memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1);
pNew->xSFunc = xSFunc;
pNew->pUserData = pArg;
pNew->funcFlags |= SQLITE_FUNC_EPHEM;
diff --git a/src/wal.c b/src/wal.c
index d7a6b701e6..bbac1bd6d0 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -546,7 +546,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset((void*)&apNew[pWal->nWiData], 0,
sizeof(u32*)*(iPage+1-pWal->nWiData));
@@ -558,7 +558,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
if( pWal->apWiData[iPage]==0 ){
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
- if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
+ if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
@@ -1173,7 +1173,7 @@ static int walIndexRecover(Wal *pWal){
szFrame = szPage + WAL_FRAME_HDRSIZE;
aFrame = (u8 *)sqlite3_malloc64(szFrame);
if( !aFrame ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
goto recovery_error;
}
aData = &aFrame[WAL_FRAME_HDRSIZE];
@@ -1311,7 +1311,7 @@ int sqlite3WalOpen(
*ppWal = 0;
pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
if( !pRet ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
pRet->pVfs = pVfs;
@@ -1575,7 +1575,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
+ iLast*sizeof(ht_slot);
p = (WalIterator *)sqlite3_malloc64(nByte);
if( !p ){
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memset(p, 0, nByte);
p->nSegment = nSegment;
@@ -1587,7 +1587,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
);
if( !aTmp ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}
for(i=0; rc==SQLITE_OK && ipData;
#endif
@@ -2909,7 +2909,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){
i64 iCksumOff;
aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE);
- if( aBuf==0 ) return SQLITE_NOMEM;
+ if( aBuf==0 ) return SQLITE_NOMEM_BKPT;
/* Find the checksum values to use as input for the recalculating the
** first checksum. If the first frame is frame 1 (implying that the current
@@ -3385,7 +3385,7 @@ int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){
pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr));
if( pRet==0 ){
- rc = SQLITE_NOMEM;
+ rc = SQLITE_NOMEM_BKPT;
}else{
memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr));
*ppSnapshot = (sqlite3_snapshot*)pRet;
diff --git a/src/where.c b/src/where.c
index 8ecdd840f3..a68dcf5bfc 100644
--- a/src/where.c
+++ b/src/where.c
@@ -31,8 +31,8 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
/*
** Return the estimated number of output rows from a WHERE clause
*/
-u64 sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
- return sqlite3LogEstToInt(pWInfo->nRowOut);
+LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){
+ return pWInfo->nRowOut;
}
/*
@@ -1736,7 +1736,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){
if( p->nLSlot>=n ) return SQLITE_OK;
n = (n+7)&~7;
paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n);
- if( paNew==0 ) return SQLITE_NOMEM;
+ if( paNew==0 ) return SQLITE_NOMEM_BKPT;
memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot);
if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm);
p->aLTerm = paNew;
@@ -1751,7 +1751,7 @@ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){
whereLoopClearUnion(db, pTo);
if( whereLoopResize(db, pTo, pFrom->nLTerm) ){
memset(&pTo->u, 0, sizeof(pTo->u));
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ);
memcpy(pTo->aLTerm, pFrom->aLTerm, pTo->nLTerm*sizeof(pTo->aLTerm[0]));
@@ -2033,7 +2033,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
if( p==0 ){
/* Allocate a new WhereLoop to add to the end of the list */
*ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop));
- if( p==0 ) return SQLITE_NOMEM;
+ if( p==0 ) return SQLITE_NOMEM_BKPT;
whereLoopInit(p);
p->pNextLoop = 0;
}else{
@@ -2189,7 +2189,7 @@ static int whereLoopAddBtreeIndex(
WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
pNew = pBuilder->pNew;
- if( db->mallocFailed ) return SQLITE_NOMEM;
+ if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
@@ -2806,7 +2806,7 @@ static int whereLoopAddVirtual(
pTab = pSrc->pTab;
assert( IsVirtual(pTab) );
pIdxInfo = allocateIndexInfo(pParse, pWC, mUnusable, pSrc,pBuilder->pOrderBy);
- if( pIdxInfo==0 ) return SQLITE_NOMEM;
+ if( pIdxInfo==0 ) return SQLITE_NOMEM_BKPT;
pNew->prereq = 0;
pNew->rSetup = 0;
pNew->wsFlags = WHERE_VIRTUALTABLE;
@@ -2816,7 +2816,7 @@ static int whereLoopAddVirtual(
nConstraint = pIdxInfo->nConstraint;
if( whereLoopResize(db, pNew, nConstraint) ){
sqlite3DbFree(db, pIdxInfo);
- return SQLITE_NOMEM;
+ return SQLITE_NOMEM_BKPT;
}
for(iPhase=0; iPhase<=3; iPhase++){
@@ -3438,6 +3438,7 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
** order.
*/
static LogEst whereSortingCost(
+ WhereInfo *pWInfo,
LogEst nRow,
int nOrderBy,
int nSorted
@@ -3458,7 +3459,15 @@ static LogEst whereSortingCost(
LogEst rScale, rSortCost;
assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
- rSortCost = nRow + estLog(nRow) + rScale + 16;
+ rSortCost = nRow + rScale + 16;
+
+ /* Multiple by log(M) where M is the number of output rows.
+ ** Use the LIMIT for M if it is smaller */
+ if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){
+ LogEst m = sqlite3LogEst(pWInfo->iLimit);
+ if( mprereq & ~pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
+ if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<10 ){
+ /* Do not use an automatic index if the this loop is expected
+ ** to run less than 2 times. */
+ assert( 10==sqlite3LogEst(2) );
+ continue;
+ }
/* At this point, pWLoop is a candidate to be the next loop.
** Compute its cost */
rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow);
@@ -3592,7 +3607,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
if( isOrdered>=0 && isOrdereddb;
memset(&sWLB, 0, sizeof(sWLB));
@@ -4065,6 +4085,7 @@ WhereInfo *sqlite3WhereBegin(
pWInfo->pResultSet = pResultSet;
pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
pWInfo->wctrlFlags = wctrlFlags;
+ pWInfo->iLimit = iAuxArg;
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
pMaskSet = &pWInfo->sMaskSet;
@@ -4145,9 +4166,14 @@ WhereInfo *sqlite3WhereBegin(
}
/* Construct the WhereLoop objects */
- WHERETRACE(0xffff,("*** Optimizer Start *** (wctrlFlags: 0x%x)\n",
- wctrlFlags));
#if defined(WHERETRACE_ENABLED)
+ if( sqlite3WhereTrace & 0xffff ){
+ sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
+ if( wctrlFlags & WHERE_USE_LIMIT ){
+ sqlite3DebugPrintf(", limit: %d", iAuxArg);
+ }
+ sqlite3DebugPrintf(")\n");
+ }
if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
int i;
for(i=0; inTerm; i++){
@@ -4330,8 +4356,8 @@ WhereInfo *sqlite3WhereBegin(
Index *pIx = pLoop->u.btree.pIndex;
int iIndexCur;
int op = OP_OpenRead;
- /* iIdxCur is always set if to a positive value if ONEPASS is possible */
- assert( iIdxCur!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
+ /* iAuxArg is always set if to a positive value if ONEPASS is possible */
+ assert( iAuxArg!=0 || (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 );
if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIx)
&& (wctrlFlags & WHERE_ONETABLE_ONLY)!=0
){
@@ -4341,7 +4367,7 @@ WhereInfo *sqlite3WhereBegin(
op = 0;
}else if( pWInfo->eOnePass!=ONEPASS_OFF ){
Index *pJ = pTabItem->pTab->pIndex;
- iIndexCur = iIdxCur;
+ iIndexCur = iAuxArg;
assert( wctrlFlags & WHERE_ONEPASS_DESIRED );
while( ALWAYS(pJ) && pJ!=pIx ){
iIndexCur++;
@@ -4349,8 +4375,8 @@ WhereInfo *sqlite3WhereBegin(
}
op = OP_OpenWrite;
pWInfo->aiCurOnePass[1] = iIndexCur;
- }else if( iIdxCur && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
- iIndexCur = iIdxCur;
+ }else if( iAuxArg && (wctrlFlags & WHERE_ONETABLE_ONLY)!=0 ){
+ iIndexCur = iAuxArg;
if( wctrlFlags & WHERE_REOPEN_IDX ) op = OP_ReopenIdx;
}else{
iIndexCur = pParse->nTab++;
diff --git a/src/whereInt.h b/src/whereInt.h
index 1a189980ef..eb6ca326f5 100644
--- a/src/whereInt.h
+++ b/src/whereInt.h
@@ -412,6 +412,7 @@ struct WhereInfo {
WhereLoop *pLoops; /* List of all WhereLoop objects */
Bitmask revMask; /* Mask of ORDER BY terms that need reversing */
LogEst nRowOut; /* Estimated number of output rows */
+ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */
u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */
i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */
u8 sorted; /* True if really sorted (not just grouped) */
diff --git a/src/wherecode.c b/src/wherecode.c
index bb48e5dc70..accc140866 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -1212,16 +1212,22 @@ Bitmask sqlite3WhereCodeOneLoopStart(
start_constraints = 1;
}
codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
- op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
- assert( op!=0 );
- sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
- VdbeCoverage(v);
- VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
- VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
- VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
- VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
- VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
- VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
+ if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){
+ /* The skip-scan logic inside the call to codeAllEqualityConstraints()
+ ** above has already left the cursor sitting on the correct row,
+ ** so no further seeking is needed */
+ }else{
+ op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
+ assert( op!=0 );
+ sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
+ VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
+ VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
+ VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
+ VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
+ VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
+ }
/* Load the value for the inequality constraint at the end of the
** range (if any).
diff --git a/src/whereexpr.c b/src/whereexpr.c
index c84d2f230a..0ad1f6a0dc 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -533,6 +533,7 @@ static void exprAnalyzeOrTerm(
if( pOrInfo==0 ) return;
pTerm->wtFlags |= TERM_ORINFO;
pOrWc = &pOrInfo->wc;
+ memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic));
sqlite3WhereClauseInit(pOrWc, pWInfo);
sqlite3WhereSplit(pOrWc, pExpr, TK_OR);
sqlite3WhereExprAnalyze(pSrc, pOrWc);
@@ -559,6 +560,7 @@ static void exprAnalyzeOrTerm(
pOrTerm->wtFlags |= TERM_ANDINFO;
pOrTerm->eOperator = WO_AND;
pAndWC = &pAndInfo->wc;
+ memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
sqlite3WhereExprAnalyze(pSrc, pAndWC);
diff --git a/test/autoindex2.test b/test/autoindex2.test
index c8abdf410a..afd4a666b7 100644
--- a/test/autoindex2.test
+++ b/test/autoindex2.test
@@ -218,10 +218,15 @@ do_execsql_test autoindex2-120 {
AND t1.did = t2.did
AND t2.uid = t3.uid
ORDER BY t1.ptime desc LIMIT 500;
-} {0 0 0 {SEARCH TABLE t1 USING INDEX t1x1 (ptime>?)} 0 1 1 {SEARCH TABLE t2 USING INDEX t2x0 (did=?)} 0 2 2 {SEARCH TABLE t3 USING INDEX t3x0 (uid=?)}}
+} {~/AUTO/}
#
# ^^^--- Before being fixed, the above was using an automatic covering
# on t3 and reordering the tables so that t3 was in the outer loop and
# implementing the ORDER BY clause using a B-Tree.
+#
+# This test is sanitized data received from a user. The original unsanitized
+# data and STAT4 data is found in the th3private test repository. See one of
+# the th3private check-ins on 2016-02-25. The test is much more accurate when
+# STAT4 data is used.
finish_test
diff --git a/test/coveridxscan.test b/test/coveridxscan.test
index 7b3c0b0be9..a8d1a8ff75 100644
--- a/test/coveridxscan.test
+++ b/test/coveridxscan.test
@@ -89,5 +89,36 @@ do_test 4.3 {
db eval {SELECT b FROM t1}
} {2 4 8}
+#-------------------------------------------------------------------------
+# Test that indexes with large numbers of columns can be correctly
+# identified as covering indexes.
+reset_db
+set L [list]
+for {set i 1} {$i<120} {incr i} {
+ lappend L "c$i"
+}
+set cols [join $L ,]
+
+do_execsql_test 5.1.0 "
+ CREATE TABLE t1(a, b, c, $cols, PRIMARY KEY(a, b, c)) WITHOUT ROWID;
+ CREATE INDEX i1 ON t1($cols);
+
+ CREATE TABLE t2(i INTEGER PRIMARY KEY, $cols);
+ CREATE INDEX i2 ON t2($cols);
+"
+
+do_eqp_test 5.1.1 {
+ SELECT * FROM t1 ORDER BY c1, c2;
+} {
+ 0 0 0 {SCAN TABLE t1 USING COVERING INDEX i1}
+}
+
+do_eqp_test 5.1.2 {
+ SELECT * FROM t2 ORDER BY c1, c2;
+} {
+ 0 0 0 {SCAN TABLE t2 USING COVERING INDEX i2}
+}
+
+
finish_test
diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c
index 03776f1e70..1e0ce86e66 100644
--- a/test/fuzzcheck.c
+++ b/test/fuzzcheck.c
@@ -70,6 +70,7 @@
#include
#include
#include "sqlite3.h"
+#include
#define ISSPACE(X) isspace((unsigned char)(X))
#define ISDIGIT(X) isdigit((unsigned char)(X))
@@ -255,8 +256,9 @@ static VFile *createVFile(const char *zName, int sz, unsigned char *pData){
if( i>=MX_FILE ) return 0;
pNew = &g.aFile[i];
if( zName ){
- pNew->zFilename = safe_realloc(0, strlen(zName)+1);
- memcpy(pNew->zFilename, zName, strlen(zName)+1);
+ int nName = (int)strlen(zName)+1;
+ pNew->zFilename = safe_realloc(0, nName);
+ memcpy(pNew->zFilename, zName, nName);
}else{
pNew->zFilename = 0;
}
@@ -620,12 +622,14 @@ static void inmemVfsRegister(void){
*/
static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){
const char *zMore;
+ const char *zEnd = &zSql[strlen(zSql)];
sqlite3_stmt *pStmt;
while( zSql && zSql[0] ){
zMore = 0;
pStmt = 0;
sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zMore);
+ assert( zMore<=zEnd );
if( zMore==zSql ) break;
if( runFlags & SQL_TRACE ){
const char *z = zSql;
@@ -783,8 +787,7 @@ static void showHelp(void){
" --export-db DIR Write databases to files(s) in DIR. Works with --dbid\n"
" --export-sql DIR Write SQL to file(s) in DIR. Also works with --sqlid\n"
" --help Show this help text\n"
-" -q Reduced output\n"
-" --quiet Reduced output\n"
+" -q|--quiet Reduced output\n"
" --limit-mem N Limit memory used by test SQLite instance to N bytes\n"
" --limit-vdbe Panic if an sync SQL runs for more than 100,000 cycles\n"
" --load-sql ARGS... Load SQL scripts fro files into SOURCE-DB\n"
@@ -795,8 +798,7 @@ static void showHelp(void){
" --result-trace Show the results of each SQL command\n"
" --sqlid N Use only SQL where sqlid=N\n"
" --timeout N Abort if any single test case needs more than N seconds\n"
-" -v Increased output\n"
-" --verbose Increased output\n"
+" -v|--verbose Increased output. Repeat for more output.\n"
);
}
@@ -919,8 +921,8 @@ int main(int argc, char **argv){
}else
if( strcmp(z,"verbose")==0 || strcmp(z,"v")==0 ){
quietFlag = 0;
- verboseFlag = 1;
- runFlags |= SQL_TRACE;
+ verboseFlag++;
+ if( verboseFlag>1 ) runFlags |= SQL_TRACE;
}else
{
fatalError("unknown option: %s", argv[i]);
@@ -1055,7 +1057,7 @@ int main(int argc, char **argv){
/* Print the description, if there is one */
if( !quietFlag ){
zDbName = azSrcDb[iSrcDb];
- i = strlen(zDbName) - 1;
+ i = (int)strlen(zDbName) - 1;
while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; }
zDbName += i;
sqlite3_prepare_v2(db, "SELECT msg FROM readme", -1, &pStmt, 0);
diff --git a/test/main.test b/test/main.test
index 3f35afe20c..9346cf6ced 100644
--- a/test/main.test
+++ b/test/main.test
@@ -319,7 +319,7 @@ do_test main-3.1 {
sqlite3 db testdb
set v [catch {execsql {SELECT * from T1 where x!!5}} msg]
lappend v $msg
-} {1 {unrecognized token: "!!"}}
+} {1 {unrecognized token: "!"}}
do_test main-3.2 {
catch {db close}
foreach f [glob -nocomplain testdb/*] {forcedelete $f}
diff --git a/test/misc1.test b/test/misc1.test
index 400a4517b4..e646bfd098 100644
--- a/test/misc1.test
+++ b/test/misc1.test
@@ -699,7 +699,7 @@ do_catchsql_test misc1-23.3 {
#
do_test misc1-24.0 {
list [catch { sqlite3_prepare_v2 db ! -1 dummy } msg] $msg
-} {1 {(1) unrecognized token: "!}}
+} {1 {(1) unrecognized token: "!"}}
# The following query (provided by Kostya Serebryany) used to take 25
# minutes to prepare. This has been speeded up to about 250 milliseconds.
diff --git a/test/pager1.test b/test/pager1.test
index 005b356080..bc9ad83fd4 100644
--- a/test/pager1.test
+++ b/test/pager1.test
@@ -529,6 +529,7 @@ set pwd [get_pwd]
testvfs tv -default 1
tv script copy_on_mj_delete
set ::mj_filename_length 0
+set ::mj_delete_cnt 0
proc copy_on_mj_delete {method filename args} {
if {[string match *mj* [file tail $filename]]} {
#
@@ -542,6 +543,7 @@ proc copy_on_mj_delete {method filename args} {
set ::mj_filename_length [string length $filename]
}
faultsim_save
+ incr ::mj_delete_cnt
}
return SQLITE_OK
}
@@ -579,29 +581,68 @@ foreach {tn1 tcl} {
}
} {
eval $tcl
- foreach {tn2 sql} {
+ foreach {tn2 sql usesMJ} {
o {
PRAGMA main.synchronous=OFF;
PRAGMA aux.synchronous=OFF;
PRAGMA journal_mode = DELETE;
- }
+ } 0
o512 {
PRAGMA main.synchronous=OFF;
PRAGMA aux.synchronous=OFF;
PRAGMA main.page_size = 512;
PRAGMA aux.page_size = 512;
PRAGMA journal_mode = DELETE;
- }
+ } 0
n {
PRAGMA main.synchronous=NORMAL;
PRAGMA aux.synchronous=NORMAL;
PRAGMA journal_mode = DELETE;
- }
+ } 1
f {
PRAGMA main.synchronous=FULL;
PRAGMA aux.synchronous=FULL;
PRAGMA journal_mode = DELETE;
- }
+ } 1
+ w1 {
+ PRAGMA main.synchronous=NORMAL;
+ PRAGMA aux.synchronous=NORMAL;
+ PRAGMA journal_mode = WAL;
+ } 0
+ w2 {
+ PRAGMA main.synchronous=NORMAL;
+ PRAGMA aux.synchronous=NORMAL;
+ PRAGMA main.journal_mode=DELETE;
+ PRAGMA aux.journal_mode=WAL;
+ } 0
+ o1a {
+ PRAGMA main.synchronous=FULL;
+ PRAGMA aux.synchronous=OFF;
+ PRAGMA journal_mode=DELETE;
+ } 0
+ o1b {
+ PRAGMA main.synchronous=OFF;
+ PRAGMA aux.synchronous=NORMAL;
+ PRAGMA journal_mode=DELETE;
+ } 0
+ m1 {
+ PRAGMA main.synchronous=NORMAL;
+ PRAGMA aux.synchronous=NORMAL;
+ PRAGMA main.journal_mode=DELETE;
+ PRAGMA aux.journal_mode = MEMORY;
+ } 0
+ t1 {
+ PRAGMA main.synchronous=NORMAL;
+ PRAGMA aux.synchronous=NORMAL;
+ PRAGMA main.journal_mode=DELETE;
+ PRAGMA aux.journal_mode = TRUNCATE;
+ } 1
+ p1 {
+ PRAGMA main.synchronous=NORMAL;
+ PRAGMA aux.synchronous=NORMAL;
+ PRAGMA main.journal_mode=DELETE;
+ PRAGMA aux.journal_mode = PERSIST;
+ } 1
} {
set tn "${tn1}.${tn2}"
@@ -613,6 +654,7 @@ foreach {tn1 tcl} {
#
tv filter xDelete
do_test pager1-4.4.$tn.1 {
+ set ::mj_delete_cnt 0
faultsim_delete_and_reopen $prefix
execsql "
ATTACH '${prefix}2' AS aux;
@@ -634,6 +676,13 @@ foreach {tn1 tcl} {
}
} {}
tv filter {}
+
+ # Verify that a master journal was deleted only for those cases where
+ # master journals really ought to be used
+ #
+ do_test pager1-4.4.$tn.1b {
+ set ::mj_delete_cnt
+ } $usesMJ
# Check that the transaction was committed successfully.
#
@@ -644,25 +693,33 @@ foreach {tn1 tcl} {
SELECT * FROM b
} {won too free double-you why zed}
- # Restore the file-system and reopen the databases. Check that it now
- # appears that the transaction was not committed (because the file-system
- # was restored to the state where it had not been).
- #
- do_test pager1-4.4.$tn.4 {
- faultsim_restore_and_reopen $prefix
- execsql "ATTACH '${prefix}2' AS aux"
- } {}
- do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
- do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
+ if {$usesMJ} {
+ # Restore the file-system and reopen the databases. Check that it now
+ # appears that the transaction was not committed (because the file-system
+ # was restored to the state where it had not been).
+ #
+ do_test pager1-4.4.$tn.4 {
+ faultsim_restore_and_reopen $prefix
+ execsql "ATTACH '${prefix}2' AS aux"
+ } {}
+ do_execsql_test pager1-4.4.$tn.5 {SELECT * FROM a} {double-you why zed}
+ do_execsql_test pager1-4.4.$tn.6 {SELECT * FROM b} {won too free}
+ }
# Restore the file-system again. This time, before reopening the databases,
# delete the master-journal file from the file-system. It now appears that
# the transaction was committed (no master-journal file == no rollback).
#
do_test pager1-4.4.$tn.7 {
- faultsim_restore_and_reopen $prefix
- foreach f [glob ${prefix}-mj*] { forcedelete $f }
+ if {$::mj_delete_cnt>0} {
+ faultsim_restore_and_reopen $prefix
+ foreach f [glob ${prefix}-mj*] { forcedelete $f }
+ } else {
+ db close
+ sqlite3 db $prefix
+ }
execsql "ATTACH '${prefix}2' AS aux"
+ glob -nocomplain ${prefix}-mj*
} {}
do_execsql_test pager1-4.4.$tn.8 {
SELECT * FROM a
@@ -678,7 +735,6 @@ db close
tv delete
forcedelete $dirname
-
# Set up a VFS to make a copy of the file-system just before deleting a
# journal file to commit a transaction. The transaction modifies exactly
# two database pages (and page 1 - the change counter).
diff --git a/test/regexp2.test b/test/regexp2.test
new file mode 100644
index 0000000000..9928e8ce8e
--- /dev/null
+++ b/test/regexp2.test
@@ -0,0 +1,125 @@
+# 2016 February 19
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+# This file implements tests for the REGEXP operator in ext/misc/regexp.c.
+# It focuses on the use of the sqlite3_set_auxdata()/get_auxdata() APIs.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix regexp2
+
+load_static_extension db regexp
+
+#-------------------------------------------------------------------------
+# Test that triggers do not become confused and use aux-data created by
+# a different trigger for a different REGEXP invocation.
+#
+do_execsql_test 1.0 {
+ CREATE TABLE t1(a, b, c);
+ CREATE TABLE x1(x, y, z);
+ CREATE TABLE x2(x, y, z);
+
+ CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
+ INSERT INTO x1 VALUES(
+ new.a REGEXP 'abc',
+ new.b REGEXP 'abc',
+ new.c REGEXP 'abc'
+ );
+ END;
+
+ CREATE TRIGGER tr2 AFTER INSERT ON t1 BEGIN
+ INSERT INTO x2 VALUES(
+ new.a REGEXP 'def',
+ new.b REGEXP 'def',
+ new.c REGEXP 'def'
+ );
+ END;
+
+ INSERT INTO t1 VALUES('abc', 'def', 'abc');
+ SELECT * FROM t1;
+} {abc def abc}
+
+do_execsql_test 1.1 { SELECT * FROM x1 } {1 0 1}
+do_execsql_test 1.2 { SELECT * FROM x2 } {0 1 0}
+
+#-------------------------------------------------------------------------
+# Test that if an exception is thrown several triggers deep, all aux-data
+# objects are cleaned up correctly.
+#
+proc sql_error {} {
+ error "SQL error!"
+}
+db func error sql_error
+do_execsql_test 2.0 {
+ CREATE TABLE t2(a, b);
+ CREATE TABLE t3(c, d);
+ CREATE TABLE t4(e, f);
+
+ CREATE TRIGGER t2_tr1 AFTER UPDATE ON t2 BEGIN
+ UPDATE t3 SET d = new.b WHERE c = old.a;
+ END;
+
+ CREATE TRIGGER t3_tr1 AFTER UPDATE ON t3 BEGIN
+ UPDATE t4 SET f = new.d WHERE e = old.c AND new.d REGEXP 'a.*';
+ END;
+
+ CREATE TRIGGER t4_tr1 AFTER UPDATE ON t4 BEGIN
+ SELECT CASE WHEN new.f REGEXP '.*y.*' THEN error() ELSE 1 END;
+ END;
+
+ INSERT INTO t2 VALUES(1, 'a_x_1');
+ INSERT INTO t2 VALUES(2, 'a_y_1');
+
+ INSERT INTO t3 VALUES(1, 'b1');
+ INSERT INTO t3 VALUES(2, 'b2');
+
+ INSERT INTO t4 VALUES(1, 'b1');
+ INSERT INTO t4 VALUES(2, 'b2');
+} {}
+
+do_catchsql_test 2.1 {
+ UPDATE t2 SET a=a+1 WHERE b REGEXP 'a.*' AND b REGEXP '.*1';
+} {1 {SQL error!}}
+
+# Test that the triggers used in the test above work as expected.
+#
+do_execsql_test 2.2 {
+ UPDATE t2 SET b = 'a_abc_1';
+} {}
+do_execsql_test 2.3 {
+ SELECT * FROM t2;
+ SELECT * FROM t3;
+ SELECT * FROM t4;
+} {1 a_abc_1 2 a_abc_1 1 a_abc_1 2 a_abc_1 1 a_abc_1 2 a_abc_1}
+
+#-------------------------------------------------------------------------
+# Test that trigger parameters (i.e. new.* and old.*) refs are not
+# considered to be constant across separate invocations of the trigger.
+#
+do_execsql_test 3.0 {
+ CREATE TABLE t5(a);
+ CREATE TABLE t6(x);
+
+ CREATE TRIGGER t5tr AFTER DELETE ON t5 BEGIN
+ DELETE FROM t6 WHERE t6.x REGEXP old.a;
+ END;
+
+ INSERT INTO t5 VALUES ('^a.*'), ('^b.*'), ('^c.*');
+ INSERT INTO t6 VALUES ('eab'), ('abc'), ('bcd'), ('cde'), ('dea');
+
+ DELETE FROM t5;
+ SELECT * FROM t6;
+} {eab dea}
+
+
+finish_test
+
diff --git a/test/speedtest1.c b/test/speedtest1.c
index b41c732053..afb446bbf1 100644
--- a/test/speedtest1.c
+++ b/test/speedtest1.c
@@ -1196,6 +1196,9 @@ int main(int argc, char **argv){
int i; /* Loop counter */
int rc; /* API return code */
+ /* Display the version of SQLite being tested */
+ printf("Speedtest1 for SQLite %s %.50s\n", sqlite3_libversion(), sqlite3_sourceid());
+
/* Process command-line arguments */
g.zWR = "";
g.zNN = "";
diff --git a/test/tester.tcl b/test/tester.tcl
index 720e15979f..47a71debed 100644
--- a/test/tester.tcl
+++ b/test/tester.tcl
@@ -374,6 +374,21 @@ proc do_not_use_codec {} {
reset_db
}
+# Print a HELP message and exit
+#
+proc print_help_and_quit {} {
+ puts {Options:
+ --pause Wait for user input before continuing
+ --soft-heap-limit=N Set the soft-heap-limit to N
+ --maxerror=N Quit after N errors
+ --verbose=(0|1) Control the amount of output. Default '1'
+ --output=FILE set --verbose=2 and output to FILE. Implies -q
+ -q Shorthand for --verbose=0
+ --help This message
+}
+ exit 1
+}
+
# The following block only runs the first time this file is sourced. It
# does not run in slave interpreters (since the ::cmdlinearg array is
# populated before the test script is run in slave interpreters).
@@ -483,6 +498,13 @@ if {[info exists cmdlinearg]==0} {
error "option --verbose= must be set to a boolean or to \"file\""
}
}
+ {.*help.*} {
+ print_help_and_quit
+ }
+ {^-q$} {
+ set cmdlinearg(output) test-out.txt
+ set cmdlinearg(verbose) 2
+ }
default {
lappend leftover $a
diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat
index 84528e37c2..c96708cef5 100755
--- a/tool/build-all-msvc.bat
+++ b/tool/build-all-msvc.bat
@@ -22,7 +22,7 @@ REM
REM Example:
REM
REM CD /D C:\dev\sqlite\core
-REM tool\build-all-msvc.bat C:\Temp
+REM CALL tool\build-all-msvc.bat C:\Temp
REM
REM In the example above, "C:\dev\sqlite\core" represents the root of the
REM source tree for SQLite and "C:\Temp" represents the final destination
@@ -54,6 +54,11 @@ REM
REM There are a few other environment variables that impact the build process
REM when set ^(to anything^), they are:
REM
+REM USE_AUTOCONF_MAKEFILE
+REM
+REM When set, the "autoconf" Makefile for MSVC will be used instead of the main
+REM Makefile for MSVC. It must exist at "%ROOT%\autoconf\Makefile.msc".
+REM
REM NOCLEAN
REM
REM When set, the "clean" target will not be used during each build iteration.
@@ -69,6 +74,11 @@ REM be skipped and they will not appear in the final destination directory.
REM Setting this environment variable is never strictly needed and could cause
REM issues in some circumstances; therefore, setting it is not recommended.
REM
+REM NOMEMDEBUG
+REM
+REM When set, disables use of MEMDEBUG when building binaries for the "Debug"
+REM configuration.
+REM
REM BUILD_ALL_SHELL
REM
REM When set, the command line shell will be built for each selected platform
@@ -88,17 +98,30 @@ REM on the WindowsSdkDir environment variable. It causes this batch script to
REM assume the Windows 10.0 SDK location should be used.
REM
REM NMAKE_ARGS
+REM NMAKE_ARGS_DEBUG
+REM NMAKE_ARGS_RETAIL
REM
-REM When set, the value is expanded and passed to the NMAKE command line, after
-REM its other arguments. This is used to specify additional NMAKE options, for
-REM example:
+REM When set, these values are expanded and passed to the NMAKE command line,
+REM after its other arguments. These may be used to specify additional NMAKE
+REM options, for example:
REM
REM SET NMAKE_ARGS=FOR_WINRT=1
+REM SET NMAKE_ARGS_DEBUG=MEMDEBUG=1
+REM SET NMAKE_ARGS_RETAIL=WIN32HEAP=1
REM
REM Using the above command before running this tool will cause the compiled
REM binaries to target the WinRT environment, which provides a subset of the
REM Win32 API.
REM
+REM DLL_FILE_NAME
+REM DLL_PDB_FILE_NAME
+REM LIB_FILE_NAME
+REM EXE_FILE_NAME
+REM EXE_PDB_FILE_NAME
+REM
+REM When set, these values will override the associated target file name used
+REM for the build.
+REM
SETLOCAL
REM SET __ECHO=ECHO
@@ -204,11 +227,17 @@ REM NOTE: If the command used to invoke NMAKE is not already set, use the
REM default.
REM
IF NOT DEFINED NMAKE_CMD (
- SET NMAKE_CMD=nmake -B -f Makefile.msc
+ IF DEFINED USE_AUTOCONF_MAKEFILE (
+ SET NMAKE_CMD=nmake -B -f autoconf\Makefile.msc
+ ) ELSE (
+ SET NMAKE_CMD=nmake -B -f Makefile.msc
+ )
)
%_VECHO% NmakeCmd = '%NMAKE_CMD%'
%_VECHO% NmakeArgs = '%NMAKE_ARGS%'
+%_VECHO% NmakeArgsDebug = '%NMAKE_ARGS_DEBUG%'
+%_VECHO% NmakeArgsRetail = '%NMAKE_ARGS_RETAIL%'
REM
REM NOTE: Setup environment variables to translate between the MSVC platform
@@ -255,6 +284,30 @@ IF NOT DEFINED %TCLSH_FILE%_PATH (
GOTO errors
)
+REM
+REM NOTE: Setup the default names for the build targets we are creating. Any
+REM ^(or all^) of these may end up being overridden.
+REM
+IF NOT DEFINED DLL_FILE_NAME (
+ SET DLL_FILE_NAME=sqlite3.dll
+)
+
+IF NOT DEFINED DLL_PDB_FILE_NAME (
+ SET DLL_PDB_FILE_NAME=sqlite3.pdb
+)
+
+IF NOT DEFINED LIB_FILE_NAME (
+ SET LIB_FILE_NAME=sqlite3.lib
+)
+
+IF NOT DEFINED EXE_FILE_NAME (
+ SET EXE_FILE_NAME=sqlite3.exe
+)
+
+IF NOT DEFINED EXE_PDB_FILE_NAME (
+ SET EXE_PDB_FILE_NAME=sqlite3sh.pdb
+)
+
REM
REM NOTE: Set the TOOLPATH variable to contain all the directories where the
REM external tools were found in the search above.
@@ -434,12 +487,20 @@ FOR %%P IN (%PLATFORMS%) DO (
REM NOTE: Setting this to non-zero should enable the SQLITE_MEMDEBUG
REM define.
REM
- SET MEMDEBUG=1
+ IF NOT DEFINED NOMEMDEBUG (
+ SET MEMDEBUG=1
+ )
) ELSE (
CALL :fn_UnsetVariable DEBUG
CALL :fn_UnsetVariable MEMDEBUG
)
+ REM
+ REM NOTE: Copy the extra NMAKE arguments for this configuration into the
+ REM common variable used by the actual commands.
+ REM
+ CALL :fn_CopyVariable NMAKE_ARGS_%%B NMAKE_ARGS_CFG
+
REM
REM NOTE: Launch a nested command shell to perform the following steps:
REM
@@ -546,7 +607,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM file, etc.
REM
IF NOT DEFINED NOCLEAN (
- %__ECHO% %NMAKE_CMD% clean
+ CALL :fn_MakeClean %%D
IF ERRORLEVEL 1 (
ECHO Failed to clean for platform %%P.
@@ -559,7 +620,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM specifically wanting to build for each platform.
REM
%_AECHO% Cleaning final core library output files only...
- %__ECHO% DEL /Q *.lo sqlite3.dll sqlite3.lib sqlite3.pdb 2%REDIRECT% NUL
+ %__ECHO% DEL /Q *.lo "%DLL_FILE_NAME%" "%LIB_FILE_NAME%" "%DLL_PDB_FILE_NAME%" 2%REDIRECT% NUL
)
REM
@@ -569,10 +630,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM Also, disable looking for and/or linking to the native Tcl
REM runtime library.
REM
- %__ECHO% %NMAKE_CMD% sqlite3.dll XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
+ CALL :fn_MakeDll %%D
IF ERRORLEVEL 1 (
- ECHO Failed to build %%B "sqlite3.dll" for platform %%P.
+ ECHO Failed to build %%B "%DLL_FILE_NAME%" for platform %%P.
GOTO errors
)
@@ -580,10 +641,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM NOTE: Copy the "sqlite3.dll" file to the appropriate directory for
REM the build and platform beneath the binary directory.
REM
- %__ECHO% XCOPY sqlite3.dll "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
+ %__ECHO% XCOPY "%DLL_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
- ECHO Failed to copy "sqlite3.dll" to "%BINARYDIRECTORY%\%%B\%%D\".
+ ECHO Failed to copy "%DLL_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
@@ -591,10 +652,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM NOTE: Copy the "sqlite3.lib" file to the appropriate directory for
REM the build and platform beneath the binary directory.
REM
- %__ECHO% XCOPY sqlite3.lib "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
+ %__ECHO% XCOPY "%LIB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
- ECHO Failed to copy "sqlite3.lib" to "%BINARYDIRECTORY%\%%B\%%D\".
+ ECHO Failed to copy "%LIB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
@@ -604,10 +665,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM are prevented from doing so.
REM
IF NOT DEFINED NOSYMBOLS (
- %__ECHO% XCOPY sqlite3.pdb "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
+ %__ECHO% XCOPY "%DLL_PDB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
- ECHO Failed to copy "sqlite3.pdb" to "%BINARYDIRECTORY%\%%B\%%D\".
+ ECHO Failed to copy "%DLL_PDB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
)
@@ -627,7 +688,7 @@ FOR %%P IN (%PLATFORMS%) DO (
REM specifically wanting to build for each platform.
REM
%_AECHO% Cleaning final shell executable output files only...
- %__ECHO% DEL /Q sqlite3.exe sqlite3sh.pdb 2%REDIRECT% NUL
+ %__ECHO% DEL /Q "%EXE_FILE_NAME%" "%EXE_PDB_FILE_NAME%" 2%REDIRECT% NUL
)
REM
@@ -637,10 +698,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM Also, disable looking for and/or linking to the native Tcl
REM runtime library.
REM
- %__ECHO% %NMAKE_CMD% sqlite3.exe XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
+ CALL :fn_MakeExe %%D
IF ERRORLEVEL 1 (
- ECHO Failed to build %%B "sqlite3.exe" for platform %%P.
+ ECHO Failed to build %%B "%EXE_FILE_NAME%" for platform %%P.
GOTO errors
)
@@ -648,10 +709,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM NOTE: Copy the "sqlite3.exe" file to the appropriate directory
REM for the build and platform beneath the binary directory.
REM
- %__ECHO% XCOPY sqlite3.exe "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
+ %__ECHO% XCOPY "%EXE_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
- ECHO Failed to copy "sqlite3.exe" to "%BINARYDIRECTORY%\%%B\%%D\".
+ ECHO Failed to copy "%EXE_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
@@ -661,10 +722,10 @@ FOR %%P IN (%PLATFORMS%) DO (
REM unless we are prevented from doing so.
REM
IF NOT DEFINED NOSYMBOLS (
- %__ECHO% XCOPY sqlite3sh.pdb "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
+ %__ECHO% XCOPY "%EXE_PDB_FILE_NAME%" "%BINARYDIRECTORY%\%%B\%%D\" %FFLAGS% %DFLAGS%
IF ERRORLEVEL 1 (
- ECHO Failed to copy "sqlite3sh.pdb" to "%BINARYDIRECTORY%\%%B\%%D\".
+ ECHO Failed to copy "%EXE_PDB_FILE_NAME%" to "%BINARYDIRECTORY%\%%B\%%D\".
GOTO errors
)
)
@@ -696,6 +757,18 @@ REM NOTE: If we get to this point, we have succeeded.
REM
GOTO no_errors
+:fn_MakeClean
+ %__ECHO% %NMAKE_CMD% clean "PLATFORM=%1" XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS% %NMAKE_ARGS_CFG%
+ GOTO :EOF
+
+:fn_MakeDll
+ %__ECHO% %NMAKE_CMD% "%DLL_FILE_NAME%" "PLATFORM=%1" XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS% %NMAKE_ARGS_CFG%
+ GOTO :EOF
+
+:fn_MakeExe
+ %__ECHO% %NMAKE_CMD% "%EXE_FILE_NAME%" "PLATFORM=%1" XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS% %NMAKE_ARGS_CFG%
+ GOTO :EOF
+
:fn_ShowVariable
SETLOCAL
SET __ECHO_CMD=ECHO %%%2%%
diff --git a/tool/lemon.c b/tool/lemon.c
index d704deb624..cefdf80174 100644
--- a/tool/lemon.c
+++ b/tool/lemon.c
@@ -286,6 +286,8 @@ struct rule {
const char **rhsalias; /* An alias for each RHS symbol (NULL if none) */
int line; /* Line number at which code begins */
const char *code; /* The code executed when this rule is reduced */
+ const char *codePrefix; /* Setup code before code[] above */
+ const char *codeSuffix; /* Breakdown code after code[] above */
struct symbol *precsym; /* Precedence symbol for this rule */
int index; /* An index number for this rule */
Boolean canReduce; /* True if this rule is ever reduced */
@@ -3430,6 +3432,7 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
int c;
char zInt[40];
if( zText==0 ){
+ if( used==0 && z!=0 ) z[0] = 0;
used = 0;
return z;
}
@@ -3466,12 +3469,21 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
** zCode is a string that is the action associated with a rule. Expand
** the symbols in this string so that the refer to elements of the parser
** stack.
+**
+** Return 1 if the expanded code requires that "yylhsminor" local variable
+** to be defined.
*/
-PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
+PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
char *cp, *xp;
int i;
- char lhsused = 0; /* True if the LHS element has been used */
- char used[MAXRHS]; /* True for each RHS element which is used */
+ int rc = 0; /* True if yylhsminor is used */
+ int dontUseRhs0 = 0; /* If true, use of left-most RHS label is illegal */
+ const char *zSkip = 0; /* The zOvwrt comment within rp->code, or NULL */
+ char lhsused = 0; /* True if the LHS element has been used */
+ char lhsdirect; /* True if LHS writes directly into stack */
+ char used[MAXRHS]; /* True for each RHS element which is used */
+ char zLhs[50]; /* Convert the LHS symbol into this string */
+ char zOvwrt[900]; /* Comment that to allow LHS to overwrite RHS */
for(i=0; inrhs; i++) used[i] = 0;
lhsused = 0;
@@ -3482,23 +3494,83 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
rp->line = rp->ruleline;
}
+
+ if( rp->lhsalias==0 ){
+ /* There is no LHS value symbol. */
+ lhsdirect = 1;
+ }else if( rp->nrhs==0 ){
+ /* If there are no RHS symbols, then writing directly to the LHS is ok */
+ lhsdirect = 1;
+ }else if( rp->rhsalias[0]==0 ){
+ /* The left-most RHS symbol has not value. LHS direct is ok. But
+ ** we have to call the distructor on the RHS symbol first. */
+ lhsdirect = 1;
+ if( has_destructor(rp->rhs[0],lemp) ){
+ append_str(0,0,0,0);
+ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
+ rp->rhs[0]->index,1-rp->nrhs);
+ rp->codePrefix = Strsafe(append_str(0,0,0,0));
+ }
+ }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){
+ /* The LHS symbol and the left-most RHS symbol are the same, so
+ ** direct writing is allowed */
+ lhsdirect = 1;
+ lhsused = 1;
+ used[0] = 1;
+ if( rp->lhs->dtnum!=rp->rhs[0]->dtnum ){
+ ErrorMsg(lemp->filename,rp->ruleline,
+ "%s(%s) and %s(%s) share the same label but have "
+ "different datatypes.",
+ rp->lhs->name, rp->lhsalias, rp->rhs[0]->name, rp->rhsalias[0]);
+ lemp->errorcnt++;
+ }
+ }else{
+ lemon_sprintf(zOvwrt, "/*%s-overwrites-%s*/",
+ rp->lhsalias, rp->rhsalias[0]);
+ zSkip = strstr(rp->code, zOvwrt);
+ if( zSkip!=0 ){
+ /* The code contains a special comment that indicates that it is safe
+ ** for the LHS label to overwrite left-most RHS label. */
+ lhsdirect = 1;
+ }else{
+ lhsdirect = 0;
+ }
+ }
+ if( lhsdirect ){
+ sprintf(zLhs, "yymsp[%d].minor.yy%d",1-rp->nrhs,rp->lhs->dtnum);
+ }else{
+ rc = 1;
+ sprintf(zLhs, "yylhsminor.yy%d",rp->lhs->dtnum);
+ }
+
append_str(0,0,0,0);
/* This const cast is wrong but harmless, if we're careful. */
for(cp=(char *)rp->code; *cp; cp++){
+ if( cp==zSkip ){
+ append_str(zOvwrt,0,0,0);
+ cp += lemonStrlen(zOvwrt)-1;
+ dontUseRhs0 = 1;
+ continue;
+ }
if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){
char saved;
for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++);
saved = *xp;
*xp = 0;
if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){
- append_str("yygotominor.yy%d",0,rp->lhs->dtnum,0);
+ append_str(zLhs,0,0,0);
cp = xp;
lhsused = 1;
}else{
for(i=0; inrhs; i++){
if( rp->rhsalias[i] && strcmp(cp,rp->rhsalias[i])==0 ){
- if( cp!=rp->code && cp[-1]=='@' ){
+ if( i==0 && dontUseRhs0 ){
+ ErrorMsg(lemp->filename,rp->ruleline,
+ "Label %s used after '%s'.",
+ rp->rhsalias[0], zOvwrt);
+ lemp->errorcnt++;
+ }else if( cp!=rp->code && cp[-1]=='@' ){
/* If the argument is of the form @X then substituted
** the token number of X, not the value of X */
append_str("yymsp[%d].major",-1,i-rp->nrhs+1,0);
@@ -3523,6 +3595,11 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
append_str(cp, 1, 0, 0);
} /* End loop */
+ /* Main code generation completed */
+ cp = append_str(0,0,0,0);
+ if( cp && cp[0] ) rp->code = Strsafe(cp);
+ append_str(0,0,0,0);
+
/* Check to make sure the LHS has been used */
if( rp->lhsalias && !lhsused ){
ErrorMsg(lemp->filename,rp->ruleline,
@@ -3531,27 +3608,55 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){
lemp->errorcnt++;
}
- /* Generate destructor code for RHS symbols which are not used in the
- ** reduce code */
+ /* Generate destructor code for RHS minor values which are not referenced.
+ ** Generate error messages for unused labels and duplicate labels.
+ */
for(i=0; inrhs; i++){
- if( rp->rhsalias[i] && !used[i] ){
- ErrorMsg(lemp->filename,rp->ruleline,
- "Label %s for \"%s(%s)\" is never used.",
- rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
- lemp->errorcnt++;
- }else if( rp->rhsalias[i]==0 ){
- if( has_destructor(rp->rhs[i],lemp) ){
- append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
- rp->rhs[i]->index,i-rp->nrhs+1);
- }else{
- /* No destructor defined for this term */
+ if( rp->rhsalias[i] ){
+ if( i>0 ){
+ int j;
+ if( rp->lhsalias && strcmp(rp->lhsalias,rp->rhsalias[i])==0 ){
+ ErrorMsg(lemp->filename,rp->ruleline,
+ "%s(%s) has the same label as the LHS but is not the left-most "
+ "symbol on the RHS.",
+ rp->rhs[i]->name, rp->rhsalias);
+ lemp->errorcnt++;
+ }
+ for(j=0; jrhsalias[j] && strcmp(rp->rhsalias[j],rp->rhsalias[i])==0 ){
+ ErrorMsg(lemp->filename,rp->ruleline,
+ "Label %s used for multiple symbols on the RHS of a rule.",
+ rp->rhsalias[i]);
+ lemp->errorcnt++;
+ break;
+ }
+ }
}
+ if( !used[i] ){
+ ErrorMsg(lemp->filename,rp->ruleline,
+ "Label %s for \"%s(%s)\" is never used.",
+ rp->rhsalias[i],rp->rhs[i]->name,rp->rhsalias[i]);
+ lemp->errorcnt++;
+ }
+ }else if( i>0 && has_destructor(rp->rhs[i],lemp) ){
+ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0,
+ rp->rhs[i]->index,i-rp->nrhs+1);
}
}
- if( rp->code ){
- cp = append_str(0,0,0,0);
- rp->code = Strsafe(cp?cp:"");
+
+ /* If unable to write LHS values directly into the stack, write the
+ ** saved LHS value now. */
+ if( lhsdirect==0 ){
+ append_str(" yymsp[%d].minor.yy%d = ", 0, 1-rp->nrhs, rp->lhs->dtnum);
+ append_str(zLhs, 0, 0, 0);
+ append_str(";\n", 0, 0, 0);
}
+
+ /* Suffix code generation complete */
+ cp = append_str(0,0,0,0);
+ if( cp ) rp->codeSuffix = Strsafe(cp);
+
+ return rc;
}
/*
@@ -3566,6 +3671,12 @@ PRIVATE void emit_code(
){
const char *cp;
+ /* Setup code prior to the #line directive */
+ if( rp->codePrefix && rp->codePrefix[0] ){
+ fprintf(out, "{%s", rp->codePrefix);
+ for(cp=rp->codePrefix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
+ }
+
/* Generate code to do the reduce action */
if( rp->code ){
if( !lemp->nolinenosflag ){
@@ -3573,15 +3684,23 @@ PRIVATE void emit_code(
tplt_linedir(out,rp->line,lemp->filename);
}
fprintf(out,"{%s",rp->code);
- for(cp=rp->code; *cp; cp++){
- if( *cp=='\n' ) (*lineno)++;
- } /* End loop */
+ for(cp=rp->code; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
fprintf(out,"}\n"); (*lineno)++;
if( !lemp->nolinenosflag ){
(*lineno)++;
tplt_linedir(out,*lineno,lemp->outname);
}
- } /* End if( rp->code ) */
+ }
+
+ /* Generate breakdown code that occurs after the #line directive */
+ if( rp->codeSuffix && rp->codeSuffix[0] ){
+ fprintf(out, "%s", rp->codeSuffix);
+ for(cp=rp->codeSuffix; *cp; cp++){ if( *cp=='\n' ) (*lineno)++; }
+ }
+
+ if( rp->codePrefix ){
+ fprintf(out, "}\n"); (*lineno)++;
+ }
return;
}
@@ -4206,8 +4325,12 @@ void ReportTable(
tplt_xfer(lemp->name,in,out,&lineno);
/* Generate code which execution during each REDUCE action */
+ i = 0;
for(rp=lemp->rule; rp; rp=rp->next){
- translate_code(lemp, rp);
+ i += translate_code(lemp, rp);
+ }
+ if( i ){
+ fprintf(out," YYMINORTYPE yylhsminor;\n"); lineno++;
}
/* First output rules other than the default: rule */
for(rp=lemp->rule; rp; rp=rp->next){
diff --git a/tool/lempar.c b/tool/lempar.c
index 312507e5f1..db7f2dbf1b 100644
--- a/tool/lempar.c
+++ b/tool/lempar.c
@@ -87,10 +87,6 @@
%%
/************* End control #defines *******************************************/
-/* The yyzerominor constant is used to initialize instances of
-** YYMINORTYPE objects to zero. */
-static const YYMINORTYPE yyzerominor = { 0 };
-
/* Define the yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
@@ -211,7 +207,9 @@ struct yyParser {
#ifdef YYTRACKMAXSTACKDEPTH
int yyidxMax; /* Maximum value of yyidx */
#endif
+#ifndef YYNOERRORRECOVERY
int yyerrcnt; /* Shifts left before out of the error */
+#endif
ParseARG_SDECL /* A place to hold %extra_argument */
#if YYSTACKDEPTH<=0
int yystksz; /* Current side of the stack */
@@ -516,7 +514,7 @@ static int yy_find_reduce_action(
/*
** The following routine is called if the stack overflows.
*/
-static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
+static void yyStackOverflow(yyParser *yypParser){
ParseARG_FETCH;
yypParser->yyidx--;
#ifndef NDEBUG
@@ -560,7 +558,7 @@ static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */
int yyNewState, /* The new state to shift in */
int yyMajor, /* The major token to shift in */
- YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
+ ParseTOKENTYPE yyMinor /* The minor token to shift in */
){
yyStackEntry *yytos;
yypParser->yyidx++;
@@ -571,14 +569,14 @@ static void yy_shift(
#endif
#if YYSTACKDEPTH>0
if( yypParser->yyidx>=YYSTACKDEPTH ){
- yyStackOverflow(yypParser, yypMinor);
+ yyStackOverflow(yypParser);
return;
}
#else
if( yypParser->yyidx>=yypParser->yystksz ){
yyGrowStack(yypParser);
if( yypParser->yyidx>=yypParser->yystksz ){
- yyStackOverflow(yypParser, yypMinor);
+ yyStackOverflow(yypParser);
return;
}
}
@@ -586,7 +584,7 @@ static void yy_shift(
yytos = &yypParser->yystack[yypParser->yyidx];
yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor;
- yytos->minor = *yypMinor;
+ yytos->minor.yy0 = yyMinor;
yyTraceShift(yypParser, yyNewState);
}
@@ -612,7 +610,6 @@ static void yy_reduce(
){
int yygoto; /* The next state */
int yyact; /* The next action */
- YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
yyStackEntry *yymsp; /* The top of the parser's stack */
int yysize; /* Amount to pop the stack */
ParseARG_FETCH;
@@ -625,7 +622,31 @@ static void yy_reduce(
yyRuleName[yyruleno], yymsp[-yysize].stateno);
}
#endif /* NDEBUG */
- yygotominor = yyzerominor;
+
+ /* Check that the stack is large enough to grow by a single entry
+ ** if the RHS of the rule is empty. This ensures that there is room
+ ** enough on the stack to push the LHS value */
+ if( yyRuleInfo[yyruleno].nrhs==0 ){
+#ifdef YYTRACKMAXSTACKDEPTH
+ if( yypParser->yyidx>yypParser->yyidxMax ){
+ yypParser->yyidxMax = yypParser->yyidx;
+ }
+#endif
+#if YYSTACKDEPTH>0
+ if( yypParser->yyidx>=YYSTACKDEPTH-1 ){
+ yyStackOverflow(yypParser);
+ return;
+ }
+#else
+ if( yypParser->yyidx>=yypParser->yystksz-1 ){
+ yyGrowStack(yypParser);
+ if( yypParser->yyidx>=yypParser->yystksz-1 ){
+ yyStackOverflow(yypParser);
+ return;
+ }
+ }
+#endif
+ }
switch( yyruleno ){
/* Beginning here are the reduction cases. A typical example
@@ -643,26 +664,17 @@ static void yy_reduce(
assert( yyruleno>=0 && yyrulenoyyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact <= YY_MAX_SHIFTREDUCE ){
if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
- /* If the reduce action popped at least
- ** one element off the stack, then we can push the new element back
- ** onto the stack here, and skip the stack overflow test in yy_shift().
- ** That gives a significant speed improvement. */
- if( yysize ){
- yypParser->yyidx++;
- yymsp -= yysize-1;
- yymsp->stateno = (YYACTIONTYPE)yyact;
- yymsp->major = (YYCODETYPE)yygoto;
- yymsp->minor = yygotominor;
- yyTraceShift(yypParser, yyact);
- }else{
- yy_shift(yypParser,yyact,yygoto,&yygotominor);
- }
+ yypParser->yyidx -= yysize - 1;
+ yymsp -= yysize-1;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
+ yyTraceShift(yypParser, yyact);
}else{
assert( yyact == YY_ACCEPT_ACTION );
+ yypParser->yyidx -= yysize;
yy_accept(yypParser);
}
}
@@ -696,10 +708,10 @@ static void yy_parse_failed(
static void yy_syntax_error(
yyParser *yypParser, /* The parser */
int yymajor, /* The major type of the error token */
- YYMINORTYPE yyminor /* The minor type of the error token */
+ ParseTOKENTYPE yyminor /* The minor type of the error token */
){
ParseARG_FETCH;
-#define TOKEN (yyminor.yy0)
+#define TOKEN yyminor
/************ Begin %syntax_error code ****************************************/
%%
/************ End %syntax_error code ******************************************/
@@ -767,14 +779,14 @@ void Parse(
if( yypParser->yyidx<0 ){
#if YYSTACKDEPTH<=0
if( yypParser->yystksz <=0 ){
- /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
- yyminorunion = yyzerominor;
- yyStackOverflow(yypParser, &yyminorunion);
+ yyStackOverflow(yypParser);
return;
}
#endif
yypParser->yyidx = 0;
+#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt = -1;
+#endif
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
#ifndef NDEBUG
@@ -784,7 +796,6 @@ void Parse(
}
#endif
}
- yyminorunion.yy0 = yyminor;
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
yyendofinput = (yymajor==0);
#endif
@@ -800,13 +811,16 @@ void Parse(
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact <= YY_MAX_SHIFTREDUCE ){
if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
- yy_shift(yypParser,yyact,yymajor,&yyminorunion);
+ yy_shift(yypParser,yyact,yymajor,yyminor);
+#ifndef YYNOERRORRECOVERY
yypParser->yyerrcnt--;
+#endif
yymajor = YYNOCODE;
}else if( yyact <= YY_MAX_REDUCE ){
yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
}else{
assert( yyact == YY_ERROR_ACTION );
+ yyminorunion.yy0 = yyminor;
#ifdef YYERRORSYMBOL
int yymx;
#endif
@@ -836,7 +850,7 @@ void Parse(
**
*/
if( yypParser->yyerrcnt<0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_syntax_error(yypParser,yymajor,yyminor);
}
yymx = yypParser->yystack[yypParser->yyidx].major;
if( yymx==YYERRORSYMBOL || yyerrorhit ){
@@ -846,10 +860,10 @@ void Parse(
yyTracePrompt,yyTokenName[yymajor]);
}
#endif
- yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
+ yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
yymajor = YYNOCODE;
}else{
- while(
+ while(
yypParser->yyidx >= 0 &&
yymx != YYERRORSYMBOL &&
(yyact = yy_find_reduce_action(
@@ -863,9 +877,7 @@ void Parse(
yy_parse_failed(yypParser);
yymajor = YYNOCODE;
}else if( yymx!=YYERRORSYMBOL ){
- YYMINORTYPE u2;
- u2.YYERRSYMDT = 0;
- yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor);
}
}
yypParser->yyerrcnt = 3;
@@ -878,7 +890,7 @@ void Parse(
** Applications can set this macro (for example inside %include) if
** they intend to abandon the parse upon the first syntax error seen.
*/
- yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_syntax_error(yypParser,yymajor, yyminor);
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
yymajor = YYNOCODE;
@@ -893,7 +905,7 @@ void Parse(
** three input tokens have been successfully shifted.
*/
if( yypParser->yyerrcnt<=0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_syntax_error(yypParser,yymajor, yyminor);
}
yypParser->yyerrcnt = 3;
yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl
index da0cd6283c..41754cd576 100644
--- a/tool/mkmsvcmin.tcl
+++ b/tool/mkmsvcmin.tcl
@@ -92,6 +92,7 @@ foreach i [lsort -integer [array names blocks]] {
set data [string map [list " -I\$(TOP)\\src" ""] $data]
set data [string map [list " /DEF:sqlite3.def" ""] $data]
set data [string map [list " sqlite3.def" ""] $data]
+set data [string map [list " libsqlite3.lib" ""] $data]
set data [string map [list " \$(ALL_TCL_TARGETS)" ""] $data]
set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data]
diff --git a/tool/mkvsix.tcl b/tool/mkvsix.tcl
index a14fd230d9..b7350f9c84 100644
--- a/tool/mkvsix.tcl
+++ b/tool/mkvsix.tcl
@@ -463,7 +463,7 @@ if {[string equal $packageFlavor WinRT]} then {
}
set shortName $shortNames($packageFlavor,$vsVersion)
set displayName $displayNames($packageFlavor,$vsVersion)
- set targetPlatformIdentifier UWP
+ set targetPlatformIdentifier UAP; # NOTE: Not "UWP".
set targetPlatformVersion v0.8.0.0
set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
set maxPlatformVersion \
diff --git a/tool/warnings.sh b/tool/warnings.sh
index 6c7cb3a8f8..cee639dc45 100644
--- a/tool/warnings.sh
+++ b/tool/warnings.sh
@@ -10,6 +10,7 @@ gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
-ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \
sqlite3.c
+if test x`uname` = 'xLinux'; then
echo '********** Android configuration ******************************'
gcc -c \
-DHAVE_USLEEP=1 \
@@ -32,6 +33,7 @@ gcc -c \
-DUSE_PREAD64 \
-Wshadow -Wall -Wextra \
-Os sqlite3.c shell.c
+fi
echo '********** No optimizations. ENABLE_STAT4. THREADSAFE=0 *******'
gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
-ansi -DSQLITE_ENABLE_STAT4 -DSQLITE_THREADSAFE=0 \