aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--VERSION2
-rw-r--r--autoconf/Makefile.msc2
-rwxr-xr-xconfigure18
-rw-r--r--ext/fts3/fts3.c2
-rw-r--r--ext/fts5/fts5_tcl.c2
-rw-r--r--ext/fts5/fts5_test_mi.c2
-rw-r--r--ext/misc/carray.c4
-rw-r--r--ext/rtree/rtree.c42
-rw-r--r--manifest81
-rw-r--r--manifest.uuid2
-rw-r--r--src/alter.c14
-rw-r--r--src/build.c33
-rw-r--r--src/callback.c4
-rw-r--r--src/func.c30
-rw-r--r--src/insert.c14
-rw-r--r--src/main.c6
-rw-r--r--src/prepare.c4
-rw-r--r--src/select.c83
-rw-r--r--src/sqlite.h.in41
-rw-r--r--src/sqlite3ext.h4
-rw-r--r--src/sqliteInt.h28
-rw-r--r--src/tclsqlite.c19
-rw-r--r--src/trigger.c2
-rw-r--r--src/vacuum.c13
-rw-r--r--src/vdbe.c6
-rw-r--r--src/vdbeInt.h15
-rw-r--r--src/vdbeapi.c28
-rw-r--r--src/vdbemem.c54
-rw-r--r--src/wherecode.c2
-rw-r--r--src/whereexpr.c32
-rw-r--r--test/colname.test55
-rw-r--r--test/like.test50
-rw-r--r--test/ossfuzz.c25
-rw-r--r--test/schema6.test163
-rw-r--r--test/without_rowid1.test14
-rw-r--r--tool/GetTclKit.bat32
36 files changed, 637 insertions, 291 deletions
diff --git a/VERSION b/VERSION
index eb9b76c9f..6075c9a9f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.20.0
+3.21.0
diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc
index 9f867986d..f0f9a01ee 100644
--- a/autoconf/Makefile.msc
+++ b/autoconf/Makefile.msc
@@ -927,7 +927,7 @@ LIBRESOBJS =
# when the shell is not being dynamically linked.
#
!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
-SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
+SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
!ENDIF
diff --git a/configure b/configure
index eb860d484..7a81d5215 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.20.0.
+# Generated by GNU Autoconf 2.69 for sqlite 3.21.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.20.0'
-PACKAGE_STRING='sqlite 3.20.0'
+PACKAGE_VERSION='3.21.0'
+PACKAGE_STRING='sqlite 3.21.0'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1463,7 +1463,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.20.0 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.21.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1528,7 +1528,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.20.0:";;
+ short | recursive ) echo "Configuration of sqlite 3.21.0:";;
esac
cat <<\_ACEOF
@@ -1652,7 +1652,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.20.0
+sqlite configure 3.21.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2071,7 +2071,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.20.0, which was
+It was created by sqlite $as_me 3.21.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12151,7 +12151,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.20.0, which was
+This file was extended by sqlite $as_me 3.21.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12217,7 +12217,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.20.0
+sqlite config.status 3.21.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c
index ca1788827..f5145426e 100644
--- a/ext/fts3/fts3.c
+++ b/ext/fts3/fts3.c
@@ -3353,7 +3353,7 @@ static int fts3ColumnMethod(
switch( iCol-p->nColumn ){
case 0:
/* The special 'table-name' column */
- sqlite3_result_pointer(pCtx, pCsr, "fts3cursor");
+ sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0);
break;
case 1:
diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c
index 99120e3d2..e8d4c32a4 100644
--- a/ext/fts5/fts5_tcl.c
+++ b/ext/fts5/fts5_tcl.c
@@ -104,7 +104,7 @@ static int SQLITE_TCLAPI f5tDbAndApi(
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
return TCL_ERROR;
}
- sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr");
+ sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr", 0);
sqlite3_step(pStmt);
if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
diff --git a/ext/fts5/fts5_test_mi.c b/ext/fts5/fts5_test_mi.c
index 49220b641..481d09b2c 100644
--- a/ext/fts5/fts5_test_mi.c
+++ b/ext/fts5/fts5_test_mi.c
@@ -75,7 +75,7 @@ static int fts5_api_from_db(sqlite3 *db, fts5_api **ppApi){
*ppApi = 0;
rc = sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0);
if( rc==SQLITE_OK ){
- sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr");
+ sqlite3_bind_pointer(pStmt, 1, (void*)ppApi, "fts5_api_ptr", 0);
(void)sqlite3_step(pStmt);
rc = sqlite3_finalize(pStmt);
}
diff --git a/ext/misc/carray.c b/ext/misc/carray.c
index b182ea1bc..b39904ae1 100644
--- a/ext/misc/carray.c
+++ b/ext/misc/carray.c
@@ -24,7 +24,7 @@
**
** static int aX[] = { 53, 9, 17, 2231, 4, 99 };
** int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
-** sqlite3_bind_value(pStmt, i, aX, "carray");
+** sqlite3_bind_value(pStmt, i, aX, "carray", 0);
**
** There is an optional third parameter to determine the datatype of
** the C-language array. Allowed values of the third parameter are
@@ -377,7 +377,7 @@ static void inttoptrFunc(
int i32 = i64 & 0xffffffff;
memcpy(&p, &i32, sizeof(p));
}
- sqlite3_result_pointer(context, p, "carray");
+ sqlite3_result_pointer(context, p, "carray", 0);
}
#endif /* SQLITE_TEST */
diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c
index 9f7d528f6..d97cb4549 100644
--- a/ext/rtree/rtree.c
+++ b/ext/rtree/rtree.c
@@ -339,14 +339,6 @@ struct RtreeGeomCallback {
void *pContext;
};
-
-/*
-** Value for the first field of every RtreeMatchArg object. The MATCH
-** operator tests that the first field of a blob operand matches this
-** value to avoid operating on invalid blobs (which could cause a segfault).
-*/
-#define RTREE_GEOMETRY_MAGIC 0x891245AB
-
/*
** An instance of this structure (in the form of a BLOB) is returned by
** the SQL functions that sqlite3_rtree_geometry_callback() and
@@ -354,7 +346,7 @@ struct RtreeGeomCallback {
** operand to the MATCH operator of an R-Tree.
*/
struct RtreeMatchArg {
- u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
+ u32 iSize; /* Size of this object */
RtreeGeomCallback cb; /* Info about the callback functions */
int nParam; /* Number of parameters to the SQL function */
sqlite3_value **apSqlParam; /* Original SQL parameter values */
@@ -1649,33 +1641,17 @@ static int findLeafNode(
** operator.
*/
static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
- RtreeMatchArg *pBlob; /* BLOB returned by geometry function */
+ RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */
sqlite3_rtree_query_info *pInfo; /* Callback information */
- int nBlob; /* Size of the geometry function blob */
- int nExpected; /* Expected size of the BLOB */
-
- /* Check that value is actually a blob. */
- if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
- /* Check that the blob is roughly the right size. */
- nBlob = sqlite3_value_bytes(pValue);
- if( nBlob<(int)sizeof(RtreeMatchArg) ){
- return SQLITE_ERROR;
- }
-
- pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
+ pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg");
+ if( pSrc==0 ) return SQLITE_ERROR;
+ pInfo = (sqlite3_rtree_query_info*)
+ sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize );
if( !pInfo ) return SQLITE_NOMEM;
memset(pInfo, 0, sizeof(*pInfo));
pBlob = (RtreeMatchArg*)&pInfo[1];
-
- memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
- nExpected = (int)(sizeof(RtreeMatchArg) +
- pBlob->nParam*sizeof(sqlite3_value*) +
- (pBlob->nParam-1)*sizeof(RtreeDValue));
- if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
- sqlite3_free(pInfo);
- return SQLITE_ERROR;
- }
+ memcpy(pBlob, pSrc, pSrc->iSize);
pInfo->pContext = pBlob->cb.pContext;
pInfo->nParam = pBlob->nParam;
pInfo->aParam = pBlob->aParam;
@@ -3713,7 +3689,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
sqlite3_result_error_nomem(ctx);
}else{
int i;
- pBlob->magic = RTREE_GEOMETRY_MAGIC;
+ pBlob->iSize = nBlob;
pBlob->cb = pGeomCtx[0];
pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
pBlob->nParam = nArg;
@@ -3730,7 +3706,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
sqlite3_result_error_nomem(ctx);
rtreeMatchArgFree(pBlob);
}else{
- sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
+ sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree);
}
}
}
diff --git a/manifest b/manifest
index d99b83ed0..1573eb1f0 100644
--- a/manifest
+++ b/manifest
@@ -1,17 +1,17 @@
-C Allow\sATTACH\sand\sDETACH\sto\soccur\sinside\sof\sa\stransaction.
-D 2017-07-26T18:26:44.412
+C Allow\sATTACH\sand\sDETACH\sinside\sof\sa\stransaction.
+D 2017-08-01T00:20:34.182
F Makefile.in d9873c9925917cca9990ee24be17eb9613a668012c85a343aef7e5536ae266e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 02b469e9dcd5b7ee63fc1fb05babc174260ee4cfa4e0ef2e48c3c6801567a016
F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd
-F VERSION 87f1498f27e398bce3da2fa8125c9879a38ed9d87e4b5fb922b351de1e25cadb
+F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0
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 1a47d071e3d5435f8f7ebff7eb6703848bbd65d4
-F autoconf/Makefile.msc 1014be616b420a5f48611d21b62ca2f50ec97ee795087ecb8a4d6bf6375ba11d
+F autoconf/Makefile.msc b77aec100e4fb4739748a2461b5aa82c179fcde35bc0e08ce52ae7322d218701
F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1
F autoconf/configure.ac 2893b823ecc86cea13739f6c8109a41392254d1db08235c5615e0af5722c8578
@@ -30,7 +30,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
-F configure 1bcc61cdd063171d8945551c265e5701a770deeff77e0ad634f8d22e4e91c831 x
+F configure 2500b432572804093c9a2516e2b16dbcec5d797ea1cd654915cfecd1d7a39ee3 x
F configure.ac 13f45f02e6c51dd0e347315b5401c3f047712b7f79b7f35619115c23755afcff
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 1f8b8d4c9f5cfe40e679fee279cc9eb2da8e6eb74ad406028538d7864cc4b6cb
@@ -70,7 +70,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c dfda8bb464d229785e0528fcf7017b4f8e95656d40d28333dfc3f3363bbe229e
+F ext/fts3/fts3.c f1c58503bc81c3dab1a70b25e146878ae40fccc716fd7c9b817995b661bc896f
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h eb2502000148e80913b965db3e59f29251266d0a
F ext/fts3/fts3_aux.c 9edc3655fcb287f0467d0a4b886a01c6185fe9f1
@@ -108,8 +108,8 @@ F ext/fts5/fts5_hash.c 32be400cf761868c9db33efe81a06eb19a17c5402ad477ee9efb51301
F ext/fts5/fts5_index.c 2ce9d50ec5508b8205615aad69e1c9b2c77f017f21d4479e1fb2079c01fdd017
F ext/fts5/fts5_main.c 24868f88ab2a865defbba7a92eebeb726cc991eb092b71b5f5508f180c72605b
F ext/fts5/fts5_storage.c fb5ef3c27073f67ade2e1bea08405f9e43f68f5f3676ed0ab7013bce5ba10be6
-F ext/fts5/fts5_tcl.c 4fab0eaba3d8a82c36195c9268e68e64c9b7acbd9e6b054e84fcf2ee97672714
-F ext/fts5/fts5_test_mi.c 03cfc256bb2dfe0d0f9516daea894ea651a7105cd3bdcfbd6c1f4d3145634931
+F ext/fts5/fts5_tcl.c a7df39442ae674dde877cf06fe02ebb7658e69c179a4d223241c90df4f14b54e
+F ext/fts5/fts5_test_mi.c 65864ba1e5c34a61d409c4c587e0bbe0466eb4f8f478d85dc42a92caad1338e6
F ext/fts5/fts5_test_tok.c ffd657dd67e7fcdb31bf63fb60b6d867299a581d0f46e97086abacd66c2a9b26
F ext/fts5/fts5_tokenize.c 2ce7b44183538ec46b7907726262ee43ffdd39a8
F ext/fts5/fts5_unicode2.c b450b209b157d598f7b9df9f837afb75a14c24bf
@@ -256,7 +256,7 @@ F ext/lsm1/test/lsm1_simple.test 3bb38951450cd1f12a6c294949334d6fbb109a3da38c48e
F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2
F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
-F ext/misc/carray.c 880684b2796ef6ad915094093297eede40db6c07f280c7f491c8eff72ea03ec7
+F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
@@ -321,7 +321,7 @@ F ext/rbu/sqlite3rbu.c d1438580a451eebda3bfd42ef69b677512f00125285e0e4e789b6131a
F ext/rbu/sqlite3rbu.h fc25e1fcd99b5c6d32b1b5b1c73122632e873ac89bd0be9bf646db362b7ce02c
F ext/rbu/test_rbu.c ec18cfc69a104309df23c359e3c80306c9a6bdd1d2c53c8b70ae158e9832dcd6
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
-F ext/rtree/rtree.c c5886d4ba7e7c66d0f9ee0b788d5532f8537ca04db19cec7f2f64dcf46e9be37
+F ext/rtree/rtree.c 4f1804b80ae06ddf7ff69192aacdceee283646dc6a328acb951f116147445212
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test 4fdd60ae034e43f2fefc26492032d02e742e8b14d468b7c51d95a1e2fa47cf00
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -388,7 +388,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c 850ede4e607f12fa25ea4f3cb6ece2b2e29d1aa50e3f786ce49d615788849552
+F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594
F src/analyze.c 0d0ccf7520a201d8747ea2f02c92c26e26f801bc161f714f27b9f7630dde0421
F src/attach.c 07b706e336fd3cedbd855e1f8266d10e82fecae07daf86717b5760cd7784c584
F src/auth.c 79f96c6f33bf0e5da8d1c282cee5ebb1852bb8a6ccca3e485d7c459b035d9c3c
@@ -398,8 +398,8 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c f55ea8f456d103328d61076be40fa39acbfea05eaa4eccfed275532a63c867c4
F src/btree.h 3edc5329bc59534d2d15b4f069a9f54b779a7e51289e98fa481ae3c0e526a5ca
F src/btreeInt.h 97700795edf8a43245720414798b7b29d8e465aef46bf301ffacd431910c0da1
-F src/build.c 74108007d286232fb4290464ee5452fa860c26215f8caa0e6c7cbf69a6fafe8f
-F src/callback.c 8e14b60d1ed1c87c02cb5f121ecda99224f2aea6524a77ee6f72c9b5c7110f84
+F src/build.c f65f86520aa877853125565e42c59c5c49851a4733392931777fb1aace4aedfd
+F src/callback.c 930648a084a3adc741c6471adfbdc50ba47ba3542421cb80a26f259f467de65e
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 928954802b1397d9fb1378c7eb702c94b4735bbab1d5793e21b6a77734f56a1b
F src/date.c 48f743d88bbe88f848532d333cca84f26e52a4f217e86f86be7fc1b919c33d74
@@ -408,16 +408,16 @@ F src/delete.c 939bd15e6b54b82b951e1c0ffc2ff2b4ab579196780a1f6d394e47bd6f799b6c
F src/expr.c fdb2fc465cabbf372fecad1fc2b291758bec74150b4db0fb945332e09df28a0e
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 5ff2c895fe087756d8085dc1a9bc229b5670e2a65c3929dd87c71e43649af333
-F src/func.c e2854b19386b93ad6b498a3f3b7d6baa98ec14cfe84530fb12fce4414263d871
+F src/func.c ed8888ae80b39f5a5d403954e4a05e0a38303523dff8143161439c142d31dec1
F src/global.c 8a6ab6b4d91effb96ffa81b39f0d70c862abca157f8aaa194600a4a8b7923344
F src/hash.c a12580e143f10301ed5166ea4964ae2853d3905a511d4e0c44497245c7ce1f7a
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c 487d2c1cd8d549f8d9492377ecc4d2f507b1bd5185e96c54389f6b607dce854c
+F src/insert.c b88a58ff7eb99365b3ff163a5771c7e5db09f43997a8c5303588056ab33bc4eb
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
F src/loadext.c 20865b183bb8a3723d59cf1efffc3c50217eb452c1021d077b908c94da26b0b2
-F src/main.c 3a9da9e3974d8a32ef6ca15b75503d540af22d284beb75bc7f0d93254ca3f8f7
+F src/main.c 42f6a2660c7a1d643cc7e863d2dcd630c6aa1e8343f5478b0592120ab84c97ba
F src/malloc.c e20bb2b48abec52d3faf01cce12e8b4f95973755fafec98d45162dfdab111978
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -447,22 +447,22 @@ F src/pcache.h 521bb9610d38ef17a3cc9b5ddafd4546c2ea67fa3d0e464823d73c2a28d50e11
F src/pcache1.c 1195a21fe28e223e024f900b2011e80df53793f0356a24caace4188b098540dc
F src/pragma.c cd6aeda3587be6c5c08f9b2d45eae6068666a03c9d077c8c43cdb85fb0aa70f2
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
-F src/prepare.c dd250f904739b1dc449c131ac527c35e3424d94082dd111321bd83f80c6bb0fe
+F src/prepare.c 1eaeccc1f9dd5b2806408e530c0f05a1972272b66d827d0a7fdc2b192b357ead
F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c 4324a94573b1e29286f8121e4881db59eaedc014afeb274c8d3e07ed282e0e20
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
-F src/select.c c6bf96a7f9d7d68f929de84738c599a30d0a725ab0b54420e70545743cd5ee7b
+F src/select.c 31b35ddf55f1021f7148a01306984b057c11ebb6e3463d94677225e0a1e301a3
F src/shell.c bd6a37cbe8bf64ef6a6a74fdc50f067d3148149b4ce2b4d03154663e66ded55f
F src/shell.c.in b5725acacba95ccefa57b6d068f710e29ba8239c3aa704628a1902a1f729c175
-F src/sqlite.h.in 6832630003ce858f55c750181488f30aa167870110d843035e501729a6a1c4cf
+F src/sqlite.h.in 0e2603c23f0747c5660669f946e231730af000c76d1653b153dcf2c26fce0a6b
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
-F src/sqlite3ext.h 967154985ed2ae62f90d9029bb5b5071793d847f1696a2ebe9e8cc0b042ae60b
-F src/sqliteInt.h 3bbfdcff01270f6db3700cb6303563b9bc429df4d0800af374002bae7312bf76
+F src/sqlite3ext.h 0f9f72b86a3792314f5db7a1dfbc2c82376bcd8d0919ceb80637bca126ec3c68
+F src/sqliteInt.h a1b8df420e8fa80fda9414ab7784d6e62271e1f7d65034ffd3e906ee6f014def
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
-F src/tclsqlite.c 2c29b0b76e91edfd1b43bf135c32c8674710089197327682b6b7e6af88062c3d
+F src/tclsqlite.c 487951d81f9704800fd9f0ffdaa2f935a83ccb6be3575c2c4ef83e4789b4c828
F src/test1.c cfb78b728b37ae3a2b14fe1b3a6c766e0da41370eda112594e698c94011b622e
F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b
@@ -515,18 +515,18 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 1003d6d90c6783206c711f0a9397656fa5b055209f4d092caa43bb3bf5215db5
F src/treeview.c 2ee4a5dada213d5ab08a742af5c876cee6f1aaae65f10a61923f3fb63846afef
-F src/trigger.c d1cae560bfacc8bfb3a072d73658245c1714c0389097da69b4cb23877a082d7e
+F src/trigger.c 48e0f7ed6749ce4d50a695e09e20ce9cf84ecabf2691852c965a51e0b620eccc
F src/update.c c443935c652af9365e033f756550b5032d02e1b06eb2cb890ed7511ae0c051dc
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
F src/util.c fc081ec6f63448dcd80d3dfad35baecfa104823254a815b081a4d9fe76e1db23
-F src/vacuum.c 874c0f2f15ab2908748297d587d22d485ea96d55aaec91d4775dddb2e24d2ecf
-F src/vdbe.c 1e541ec7ff409bbabcc6b4f154957296fff5827c16c2ab0056348acae75685bf
+F src/vacuum.c 90839322fd5f00df9617eb21b68beda9b6e2a2937576b0d65985e4aeb1c53739
+F src/vdbe.c ac9cc205741b295d5b77917cfd2a45632de3cd5563e143e74dce1ede42e4b68c
F src/vdbe.h d50cadf12bcf9fb99117ef392ce1ea283aa429270481426b6e8b0280c101fd97
-F src/vdbeInt.h 19bd04a4211fe56c712ab35b48be77fd5a0579b851e9dea2cb8deade359b72b9
-F src/vdbeapi.c 52844a5a71712197be45f1c63d730c48a745c7457c959465cfb2b969af40a266
+F src/vdbeInt.h ff2b7db0968d20e6184aee256d2e535d565f5a172e3588a78adb166a41fc4911
+F src/vdbeapi.c 0823531191f9d5588a245ed5b39306798681814e9e8099d54a3213a13a28fbe7
F src/vdbeaux.c 3fe68bad02b33b09e08bdc0ad90d6b92b3d571f7864c3d047abca1bde050751c
F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9
-F src/vdbemem.c fe8fce1cdc258320b465934039fe4b1230d63f81d6b81b1eac775b6eec00af0d
+F src/vdbemem.c 9ca2854976f35db40341977e688a08204c96427505f5b90215dc7970f6ea42c4
F src/vdbesort.c f512c68d0bf7e0105316a5594c4329358c8ee9cae3b25138df041d97516c0372
F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
@@ -536,8 +536,8 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71
F src/walker.c a7ca64ce08a83a20d32186fbe06bca9234e348cfcf07959ee322fdc3e8a6173a
F src/where.c cbe8ddffbcec7ce86f7a800fe8fd10aee412c76c87e0dd3732a1682e68d74cd9
F src/whereInt.h 93bb90b77d39901eda31b44d8e90da1351193ccfe96876f89b58a93a33b84c3d
-F src/wherecode.c c0c4c31573486cd14bb2cbfc63e41eda591609e5190416261999f211bf97abc1
-F src/whereexpr.c bf983d2d33e325cd63a36c40b8de289fd3d7b4d9f2db9052fb8f59f7161a34a0
+F src/wherecode.c e7be3b7f4c11908500cdf02b299d190d3742659533f58e0f4047962fdb5a48da
+F src/whereexpr.c 35d8b33afeedb8009fcd7211e1c848587578b345da93dbed69edc88dffe64c35
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d
@@ -652,7 +652,7 @@ F test/collate9.test 3adcc799229545940df2f25308dd1ad65869145a
F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6
F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95
F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1
-F test/colname.test 08948a4809d22817e0e5de89c7c0a8bd90cb551b
+F test/colname.test b111edd2a84f558567320904bb94c779d7eec47254265b5f0a3d1f3e52cc28e0
F test/conflict.test 029faa2d81a0d1cafb5f88614beb663d972c01db
F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c
F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9
@@ -978,7 +978,7 @@ F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/kvtest.c d2b8cfc91047ebf6cac4f3a04f19c3a864e4ecfd683bbb65c395df450b8dc79c
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
-F test/like.test 3d26ae14d7042a0e96f7b0b9e9ad2c8ca6ed122772439c6b1c691fe167e15a37
+F test/like.test 67d7431c9b664254febce9e90fd2f47c7c75c8b38444e2a50ef9ec2776b84ca8
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 3608a2042b6f922f900fbfd5d3ce4e7eca57f7c4
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
@@ -1071,7 +1071,7 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da
F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd
F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3
F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f
-F test/ossfuzz.c f5abed3177f719df3c3109901fcdd26b9fb7f581c8da50fc26f3a81ddfb2c2ae
+F test/ossfuzz.c 7f5cc87a0280a5854c1bfa7d5c4d07d34731f08ec34dc9c916aa35ed292b1468
F test/ossshell.c 296ab63067841bd1b1e97b46a0b2af48ee7f69d50d1a723008bee12dd7122622
F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f
F test/pager1.test 8149b2a8986fee667ab6a8171ab310be19e77ae215bebad0e90c857b0df1935c
@@ -1144,6 +1144,7 @@ F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
F test/schema4.test 3b26c9fa916abb6dadf894137adcf41b7796f7b9
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
+F test/schema6.test 5b21bbdd405bc93b3e6af5e6ece64d230e35f65cc4035e5c2b89fc8a090d7270
F test/securedel.test 5f997cb6bd38727b81e0985f53ec386c99db6441b2b9e6357240649d29017239
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686
@@ -1535,7 +1536,7 @@ F test/with1.test 732e3ef398dcecb609839cd5ef0cb63beb2a9eff31420f3b745fc55b9e85b6
F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87
F test/with3.test e71604a0e53cba82bc04c703987cb1d6751ec0b6
F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64
-F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701
+F test/without_rowid1.test 06b7215130882d6a072233820dd364c874c4fd69221e8fc756ec471009192874
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test 2724c787a51a5dce09d078453a758117b4b728f1
F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a
@@ -1545,7 +1546,7 @@ F test/wordcount.c 06efb84b7c48a4973c2c24ea06c93d00bce24389
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
-F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7
+F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/addopcodes.tcl edbd53806bf20e25af2373ad0c091be4385081c1aa1813b916bf093f94ed8380
F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x
@@ -1637,10 +1638,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 622b108915c7982b29ca9920abde941fff55234b70af9ac4122e4827b35d985c
-R c8a5d4e1b277f24239b70c74c58b2a5c
-T *branch * attach-in-trans
-T *sym-attach-in-trans *
-T -sym-trunk *
+P 0c77935cf9949099d834ec51384c1d4dcdaf7b4422c859c9fce6d3cb3bde2645 ac1fd6beb6c804af5faf1e06a51177a8316007ff9e718c398bd7a24d2ecc4ed3
+R 0baf627cb47530fd453d60ae728f6e16
+T +closed ac1fd6beb6c804af5faf1e06a51177a8316007ff9e718c398bd7a24d2ecc4ed3
U drh
-Z 1f8b86f42dfa6db3f69a52ef8e583d3f
+Z 5c8b473184a93b34c81627bf252d49c0
diff --git a/manifest.uuid b/manifest.uuid
index 1bf1aac23..951d33a66 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-ac1fd6beb6c804af5faf1e06a51177a8316007ff9e718c398bd7a24d2ecc4ed3 \ No newline at end of file
+95e8f31658254dd2df3eeaae337aff0fe2125d170ae966c74f4fc70400e099b1 \ No newline at end of file
diff --git a/src/alter.c b/src/alter.c
index 8df06f064..51d4a4006 100644
--- a/src/alter.c
+++ b/src/alter.c
@@ -403,9 +403,9 @@ void sqlite3AlterRenameTable(
char *zWhere = 0; /* Where clause to locate temp triggers */
#endif
VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */
- int savedDbFlags; /* Saved value of db->flags */
+ u32 savedDbFlags; /* Saved value of db->mDbFlags */
- savedDbFlags = db->flags;
+ savedDbFlags = db->mDbFlags;
if( NEVER(db->mallocFailed) ) goto exit_rename_table;
assert( pSrc->nSrc==1 );
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
@@ -414,7 +414,7 @@ void sqlite3AlterRenameTable(
if( !pTab ) goto exit_rename_table;
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
zDb = db->aDb[iDb].zDbSName;
- db->flags |= SQLITE_PreferBuiltin;
+ db->mDbFlags |= DBFLAG_PreferBuiltin;
/* Get a NULL terminated version of the new table name. */
zName = sqlite3NameFromToken(db, pName);
@@ -579,7 +579,7 @@ void sqlite3AlterRenameTable(
exit_rename_table:
sqlite3SrcListDelete(db, pSrc);
sqlite3DbFree(db, zName);
- db->flags = savedDbFlags;
+ db->mDbFlags = savedDbFlags;
}
/*
@@ -680,11 +680,11 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
if( zCol ){
char *zEnd = &zCol[pColDef->n-1];
- int savedDbFlags = db->flags;
+ u32 savedDbFlags = db->mDbFlags;
while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
*zEnd-- = '\0';
}
- db->flags |= SQLITE_PreferBuiltin;
+ db->mDbFlags |= DBFLAG_PreferBuiltin;
sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET "
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
@@ -693,7 +693,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
zTab
);
sqlite3DbFree(db, zCol);
- db->flags = savedDbFlags;
+ db->mDbFlags = savedDbFlags;
}
/* Make sure the schema version is at least 3. But do not upgrade
diff --git a/src/build.c b/src/build.c
index cc05bdfb9..8eab3823c 100644
--- a/src/build.c
+++ b/src/build.c
@@ -479,7 +479,7 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
}
freeIndex(db, pIndex);
}
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
/*
@@ -551,7 +551,7 @@ void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
sqlite3SchemaClear(pDb->pSchema);
}
}
- db->flags &= ~SQLITE_InternChanges;
+ db->mDbFlags &= ~DBFLAG_SchemaChange;
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
sqlite3CollapseDatabaseArray(db);
@@ -561,7 +561,7 @@ void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
** This routine is called when a commit occurs.
*/
void sqlite3CommitInternalChanges(sqlite3 *db){
- db->flags &= ~SQLITE_InternChanges;
+ db->mDbFlags &= ~DBFLAG_SchemaChange;
}
/*
@@ -665,7 +665,7 @@ void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
pDb = &db->aDb[iDb];
p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
sqlite3DeleteTable(db, p);
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
/*
@@ -778,7 +778,8 @@ int sqlite3TwoPartName(
return -1;
}
}else{
- assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
+ assert( db->init.iDb==0 || db->init.busy
+ || (db->mDbFlags & DBFLAG_Vacuum)!=0);
iDb = db->init.iDb;
*pUnqual = pName1;
}
@@ -1738,15 +1739,6 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
}else{
pPk = sqlite3PrimaryKeyIndex(pTab);
- /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
- ** table entry. This is only required if currently generating VDBE
- ** code for a CREATE TABLE (not when parsing one as part of reading
- ** a database schema). */
- if( v ){
- assert( db->init.busy==0 );
- sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
- }
-
/*
** Remove all redundant columns from the PRIMARY KEY. For example, change
** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
@@ -1766,6 +1758,15 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
if( !db->init.imposterTable ) pPk->uniqNotNull = 1;
nPk = pPk->nKeyCol;
+ /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
+ ** table entry. This is only required if currently generating VDBE
+ ** code for a CREATE TABLE (not when parsing one as part of reading
+ ** a database schema). */
+ if( v && pPk->tnum>0 ){
+ assert( db->init.busy==0 );
+ sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto);
+ }
+
/* The root page of the PRIMARY KEY is the table root page */
pPk->tnum = pTab->tnum;
@@ -2055,7 +2056,7 @@ void sqlite3EndTable(
return;
}
pParse->pNewTable = 0;
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
#ifndef SQLITE_OMIT_ALTERTABLE
if( !p->pSelect ){
@@ -3324,7 +3325,7 @@ void sqlite3CreateIndex(
sqlite3OomFault(db);
goto exit_create_index;
}
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
if( pTblName!=0 ){
pIndex->tnum = db->init.newTnum;
}
diff --git a/src/callback.c b/src/callback.c
index 5fe103686..10505414c 100644
--- a/src/callback.c
+++ b/src/callback.c
@@ -374,7 +374,7 @@ FuncDef *sqlite3FindFunction(
/* If no match is found, search the built-in functions.
**
- ** If the SQLITE_PreferBuiltin flag is set, then search the built-in
+ ** If the DBFLAG_PreferBuiltin flag is set, then search the built-in
** functions even if a prior app-defined function was found. And give
** priority to built-in functions.
**
@@ -384,7 +384,7 @@ FuncDef *sqlite3FindFunction(
** new function. But the FuncDefs for built-in functions are read-only.
** So we must not search for built-ins when creating a new function.
*/
- if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){
+ if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){
bestScore = 0;
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % SQLITE_FUNC_HASH_SZ;
p = functionSearch(h, zName);
diff --git a/src/func.c b/src/func.c
index fd5458ad3..2bb9a91de 100644
--- a/src/func.c
+++ b/src/func.c
@@ -1706,9 +1706,14 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
/*
** pExpr points to an expression which implements a function. If
** it is appropriate to apply the LIKE optimization to that function
-** then set aWc[0] through aWc[2] to the wildcard characters and
-** return TRUE. If the function is not a LIKE-style function then
-** return FALSE.
+** then set aWc[0] through aWc[2] to the wildcard characters and the
+** escape character and then return TRUE. If the function is not a
+** LIKE-style function then return FALSE.
+**
+** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE
+** operator if c is a string literal that is exactly one byte in length.
+** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is
+** no ESCAPE clause.
**
** *pIsNocase is set to true if uppercase and lowercase are equivalent for
** the function (default for LIKE). If the function makes the distinction
@@ -1717,17 +1722,26 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){
*/
int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
FuncDef *pDef;
- if( pExpr->op!=TK_FUNCTION
- || !pExpr->x.pList
- || pExpr->x.pList->nExpr!=2
- ){
+ int nExpr;
+ if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){
return 0;
}
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
- pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0);
+ nExpr = pExpr->x.pList->nExpr;
+ pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
return 0;
}
+ if( nExpr<3 ){
+ aWc[3] = 0;
+ }else{
+ Expr *pEscape = pExpr->x.pList->a[2].pExpr;
+ char *zEscape;
+ if( pEscape->op!=TK_STRING ) return 0;
+ zEscape = pEscape->u.zToken;
+ if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
+ aWc[3] = zEscape[0];
+ }
/* The memcpy() statement assumes that the wildcard characters are
** the first three statements in the compareInfo structure. The
diff --git a/src/insert.c b/src/insert.c
index 20e3736d7..d51e64b8f 100644
--- a/src/insert.c
+++ b/src/insert.c
@@ -226,7 +226,7 @@ static int autoIncBegin(
){
int memId = 0; /* Register holding maximum rowid */
if( (pTab->tabFlags & TF_Autoincrement)!=0
- && (pParse->db->flags & SQLITE_Vacuum)==0
+ && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0
){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
AutoincInfo *pInfo;
@@ -2059,7 +2059,7 @@ static int xferOptimization(
Column *pDestCol = &pDest->aCol[i];
Column *pSrcCol = &pSrc->aCol[i];
#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
- if( (db->flags & SQLITE_Vacuum)==0
+ if( (db->mDbFlags & DBFLAG_Vacuum)==0
&& (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN
){
return 0; /* Neither table may have __hidden__ columns */
@@ -2135,15 +2135,15 @@ static int xferOptimization(
regRowid = sqlite3GetTempReg(pParse);
sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
assert( HasRowid(pDest) || destHasUniqueIdx );
- if( (db->flags & SQLITE_Vacuum)==0 && (
+ if( (db->mDbFlags & DBFLAG_Vacuum)==0 && (
(pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */
|| destHasUniqueIdx /* (2) */
|| (onError!=OE_Abort && onError!=OE_Rollback) /* (3) */
)){
/* In some circumstances, we are able to run the xfer optimization
** only if the destination table is initially empty. Unless the
- ** SQLITE_Vacuum flag is set, this block generates code to make
- ** that determination. If SQLITE_Vacuum is set, then the destination
+ ** DBFLAG_Vacuum flag is set, this block generates code to make
+ ** that determination. If DBFLAG_Vacuum is set, then the destination
** table is always empty.
**
** Conditions under which the destination must be empty:
@@ -2179,7 +2179,7 @@ static int xferOptimization(
assert( (pDest->tabFlags & TF_Autoincrement)==0 );
}
sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
- if( db->flags & SQLITE_Vacuum ){
+ if( db->mDbFlags & DBFLAG_Vacuum ){
sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|
OPFLAG_APPEND|OPFLAG_USESEEKRESULT;
@@ -2211,7 +2211,7 @@ static int xferOptimization(
VdbeComment((v, "%s", pDestIdx->zName));
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
- if( db->flags & SQLITE_Vacuum ){
+ if( db->mDbFlags & DBFLAG_Vacuum ){
/* This INSERT command is part of a VACUUM operation, which guarantees
** that the destination table is empty. If all indexed columns use
** collation sequence BINARY, then it can also be assumed that the
diff --git a/src/main.c b/src/main.c
index 747c25ea8..2d8135837 100644
--- a/src/main.c
+++ b/src/main.c
@@ -824,7 +824,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
if( aFlagOp[i].op==op ){
int onoff = va_arg(ap, int);
int *pRes = va_arg(ap, int*);
- int oldFlags = db->flags;
+ u32 oldFlags = db->flags;
if( onoff>0 ){
db->flags |= aFlagOp[i].mask;
}else if( onoff==0 ){
@@ -1259,7 +1259,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** the database rollback and schema reset, which can cause false
** corruption reports in some cases. */
sqlite3BtreeEnterAll(db);
- schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0;
+ schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0;
for(i=0; i<db->nDb; i++){
Btree *p = db->aDb[i].pBt;
@@ -1273,7 +1273,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
- if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){
+ if( (db->mDbFlags&DBFLAG_SchemaChange)!=0 && db->init.busy==0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
}
diff --git a/src/prepare.c b/src/prepare.c
index 17fbf66d3..cb3d5afee 100644
--- a/src/prepare.c
+++ b/src/prepare.c
@@ -85,7 +85,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
- assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
+ assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 );
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
@@ -354,7 +354,7 @@ error_out:
*/
int sqlite3Init(sqlite3 *db, char **pzErrMsg){
int i, rc;
- int commit_internal = !(db->flags&SQLITE_InternChanges);
+ int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange);
assert( sqlite3_mutex_held(db->mutex) );
assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
diff --git a/src/select.c b/src/select.c
index a3ada4ef7..9af93dc9e 100644
--- a/src/select.c
+++ b/src/select.c
@@ -1438,13 +1438,10 @@ static const char *columnTypeImpl(
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
- if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
+ if( iCol>=0 && iCol<pS->pEList->nExpr ){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
- **
- ** The ALWAYS() is because iCol>=pS->pEList->nExpr will have been
- ** caught already by name resolution.
*/
NameContext sNC;
Expr *p = pS->pEList->a[iCol].pExpr;
@@ -1554,18 +1551,6 @@ static void generateColumnTypes(
#endif /* !defined(SQLITE_OMIT_DECLTYPE) */
}
-/*
-** Return the Table objecct in the SrcList that has cursor iCursor.
-** Or return NULL if no such Table object exists in the SrcList.
-*/
-static Table *tableWithCursor(SrcList *pList, int iCursor){
- int j;
- for(j=0; j<pList->nSrc; j++){
- if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab;
- }
- return 0;
-}
-
/*
** Compute the column names for a SELECT statement.
@@ -1599,15 +1584,16 @@ static Table *tableWithCursor(SrcList *pList, int iCursor){
*/
static void generateColumnNames(
Parse *pParse, /* Parser context */
- SrcList *pTabList, /* The FROM clause of the SELECT */
- ExprList *pEList /* Expressions defining the result set */
+ Select *pSelect /* Generate column names for this SELECT statement */
){
Vdbe *v = pParse->pVdbe;
int i;
Table *pTab;
+ SrcList *pTabList;
+ ExprList *pEList;
sqlite3 *db = pParse->db;
- int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
- int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
+ int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */
+ int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */
#ifndef SQLITE_OMIT_EXPLAIN
/* If this is an EXPLAIN, skip this step */
@@ -1617,6 +1603,10 @@ static void generateColumnNames(
#endif
if( pParse->colNamesSet || db->mallocFailed ) return;
+ /* Column names are determined by the left-most term of a compound select */
+ while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+ pTabList = pSelect->pSrc;
+ pEList = pSelect->pEList;
assert( v!=0 );
assert( pTabList!=0 );
pParse->colNamesSet = 1;
@@ -1631,12 +1621,11 @@ static void generateColumnNames(
/* An AS clause always takes first priority */
char *zName = pEList->a[i].zName;
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
- }else if( srcName
- && (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN)
- && (pTab = tableWithCursor(pTabList, p->iTable))!=0
- ){
+ }else if( srcName && p->op==TK_COLUMN ){
char *zCol;
int iCol = p->iColumn;
+ pTab = p->pTab;
+ assert( pTab!=0 );
if( iCol<0 ) iCol = pTab->iPKey;
assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
if( iCol<0 ){
@@ -2468,11 +2457,6 @@ static int multiSelect(
if( dest.eDest!=priorOp ){
int iCont, iBreak, iStart;
assert( p->pEList );
- if( dest.eDest==SRT_Output ){
- Select *pFirst = p;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
- }
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
@@ -2543,11 +2527,6 @@ static int multiSelect(
** tables.
*/
assert( p->pEList );
- if( dest.eDest==SRT_Output ){
- Select *pFirst = p;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
- }
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
@@ -3155,14 +3134,6 @@ static int multiSelectOrderBy(
*/
sqlite3VdbeResolveLabel(v, labelEnd);
- /* Set the number of output columns
- */
- if( pDest->eDest==SRT_Output ){
- Select *pFirst = pPrior;
- while( pFirst->pPrior ) pFirst = pFirst->pPrior;
- generateColumnNames(pParse, pFirst->pSrc, pFirst->pEList);
- }
-
/* Reassembly the compound query so that it will be freed correctly
** by the calling function */
if( p->pPrior ){
@@ -3457,7 +3428,6 @@ static int flattenSubquery(
Select *pSub1; /* Pointer to the rightmost select in sub-query */
SrcList *pSrc; /* The FROM clause of the outer query */
SrcList *pSubSrc; /* The FROM clause of the subquery */
- ExprList *pList; /* The result set of the outer query */
int iParent; /* VDBE cursor number of the pSub result set temp table */
int iNewParent = -1;/* Replacement table for iParent */
int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
@@ -3782,14 +3752,6 @@ static int flattenSubquery(
** We look at every expression in the outer query and every place we see
** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
*/
- pList = pParent->pEList;
- for(i=0; i<pList->nExpr; i++){
- if( pList->a[i].zName==0 ){
- char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
- sqlite3Dequote(zName);
- pList->a[i].zName = zName;
- }
- }
if( pSub->pOrderBy ){
/* At this point, any non-zero iOrderByCol values indicate that the
** ORDER BY column expression is identical to the iOrderByCol'th
@@ -5219,6 +5181,14 @@ int sqlite3Select(
}
#endif
+ /* Get a pointer the VDBE under construction, allocating a new VDBE if one
+ ** does not already exist */
+ v = sqlite3GetVdbe(pParse);
+ if( v==0 ) goto select_end;
+ if( pDest->eDest==SRT_Output ){
+ generateColumnNames(pParse, p);
+ }
+
/* Try to flatten subqueries in the FROM clause up into the main query
*/
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
@@ -5254,11 +5224,6 @@ int sqlite3Select(
}
#endif
- /* Get a pointer the VDBE under construction, allocating a new VDBE if one
- ** does not already exist */
- v = sqlite3GetVdbe(pParse);
- if( v==0 ) goto select_end;
-
#ifndef SQLITE_OMIT_COMPOUND_SELECT
/* Handle compound SELECT statements using the separate multiSelect()
** procedure.
@@ -6058,12 +6023,6 @@ int sqlite3Select(
select_end:
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
- /* Identify column names if results of the SELECT are to be output.
- */
- if( rc==SQLITE_OK && pDest->eDest==SRT_Output ){
- generateColumnNames(pParse, pTabList, pEList);
- }
-
sqlite3DbFree(db, sAggInfo.aCol);
sqlite3DbFree(db, sAggInfo.aFunc);
#if SELECTTRACE_ENABLED
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index ea002b720..e8f34e4ab 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -3883,19 +3883,14 @@ typedef struct sqlite3_context sqlite3_context;
** [sqlite3_blob_open | incremental BLOB I/O] routines.
** ^A negative value for the zeroblob results in a zero-length BLOB.
**
-** ^The sqlite3_bind_pointer(S,I,P,T) routine causes the I-th parameter in
+** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in
** [prepared statement] S to have an SQL value of NULL, but to also be
-** associated with the pointer P of type T.
-** ^The sqlite3_bind_pointer() routine can be used to pass
-** host-language pointers into [application-defined SQL functions].
-** ^A parameter that is initialized using [sqlite3_bind_pointer()] appears
-** to be an ordinary SQL NULL value to everything other than
-** [sqlite3_value_pointer()]. The T parameter should be a static string,
-** preferably a string literal. The procedure that invokes
-** sqlite3_bind_pointer(S,I,P,T) continues to own the P and T pointers and
-** must guarantee that those pointers remain valid until after the last
-** access via [sqlite3_value_pointer()]. The sqlite3_bind_pointer() routine
-** is part of the [pointer passing interface] added for SQLite 3.20.0.
+** associated with the pointer P of type T. ^D is either a NULL pointer or
+** a pointer to a destructor function for P. ^SQLite will invoke the
+** destructor D with a single argument of P when it is finished using
+** P. The T parameter should be a static string, preferably a string
+** literal. The sqlite3_bind_pointer() routine is part of the
+** [pointer passing interface] added for SQLite 3.20.0.
**
** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer
** for the [prepared statement] or with a prepared statement for which
@@ -3930,7 +3925,7 @@ int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
void(*)(void*), unsigned char encoding);
int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*);
+int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*));
int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64);
@@ -4763,10 +4758,11 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
** extract UTF-16 strings as big-endian and little-endian respectively.
**
** ^If [sqlite3_value] object V was initialized
-** using [sqlite3_bind_pointer(S,I,P,X)] or [sqlite3_result_pointer(C,P,X)]
+** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)]
** and if X and Y are strings that compare equal according to strcmp(X,Y),
** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise,
-** sqlite3_value_pointer(V,Y) returns a NULL.
+** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer()
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
**
** ^(The sqlite3_value_type(V) interface returns the
** [SQLITE_INTEGER | datatype code] for the initial datatype of the
@@ -5101,17 +5097,16 @@ typedef void (*sqlite3_destructor_type)(void*);
** [unprotected sqlite3_value] object is required, so either
** kind of [sqlite3_value] object can be used with this interface.
**
-** ^The sqlite3_result_pointer(C,P,T) interface sets the result to an
+** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an
** SQL NULL value, just like [sqlite3_result_null(C)], except that it
** also associates the host-language pointer P or type T with that
** NULL value such that the pointer can be retrieved within an
** [application-defined SQL function] using [sqlite3_value_pointer()].
-** The T parameter should be a static string and preferably a string
-** literal. The procedure that invokes sqlite3_result_pointer(C,P,T)
-** continues to own the P and T pointers and must guarantee that
-** those pointers remain valid until after the last access via
-** [sqlite3_value_pointer()]. The sqlite3_result_pointer() routine
-** is part of the [pointer passing interface] added for SQLite 3.20.0.
+** ^If the D parameter is not NULL, then it is a pointer to a destructor
+** for the P parameter. ^SQLite invokes D with P as its only argument
+** when SQLite is finished with P. The T parameter should be a static
+** string and preferably a string literal. The sqlite3_result_pointer()
+** routine is part of the [pointer passing interface] added for SQLite 3.20.0.
**
** If these routines are called from within the different thread
** than the one containing the application-defined function that received
@@ -5136,7 +5131,7 @@ void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-void sqlite3_result_pointer(sqlite3_context*, void*, const char*);
+void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*));
void sqlite3_result_zeroblob(sqlite3_context*, int n);
int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n);
diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h
index c585f17f2..0f1712bee 100644
--- a/src/sqlite3ext.h
+++ b/src/sqlite3ext.h
@@ -289,8 +289,8 @@ struct sqlite3_api_routines {
sqlite3_stmt**,const char**);
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
sqlite3_stmt**,const void**);
- int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*);
- void (*result_pointer)(sqlite3_context*,void*,const char*);
+ int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
+ void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
void *(*value_pointer)(sqlite3_value*,const char*);
};
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 2d19849da..724cd5312 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1316,7 +1316,8 @@ struct sqlite3 {
sqlite3_mutex *mutex; /* Connection mutex */
Db *aDb; /* All backends */
int nDb; /* Number of backends currently in use */
- int flags; /* Miscellaneous flags. See below */
+ u32 mDbFlags; /* flags recording internal state */
+ u32 flags; /* flags settable by pragmas. See below */
i64 lastRowid; /* ROWID of most recent insert (see above) */
i64 szMmap; /* Default mmap_size setting */
unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */
@@ -1470,18 +1471,13 @@ struct sqlite3 {
#define SQLITE_ForeignKeys 0x00004000 /* Enforce foreign key constraints */
#define SQLITE_AutoIndex 0x00008000 /* Enable automatic indexes */
#define SQLITE_LoadExtension 0x00010000 /* Enable load_extension */
-#define SQLITE_EnableTrigger 0x00020000 /* True to enable triggers */
-#define SQLITE_DeferFKs 0x00040000 /* Defer all FK constraints */
-#define SQLITE_QueryOnly 0x00080000 /* Disable database changes */
-#define SQLITE_CellSizeCk 0x00100000 /* Check btree cell sizes on load */
-#define SQLITE_Fts3Tokenizer 0x00200000 /* Enable fts3_tokenizer(2) */
-#define SQLITE_EnableQPSG 0x00400000 /* Query Planner Stability Guarantee */
-/* The next four values are not used by PRAGMAs or by sqlite3_dbconfig() and
-** could be factored out into a separate bit vector of the sqlite3 object. */
-#define SQLITE_InternChanges 0x00800000 /* Uncommitted Hash table changes */
-#define SQLITE_LoadExtFunc 0x01000000 /* Enable load_extension() SQL func */
-#define SQLITE_PreferBuiltin 0x02000000 /* Preference to built-in funcs */
-#define SQLITE_Vacuum 0x04000000 /* Currently in a VACUUM */
+#define SQLITE_LoadExtFunc 0x00020000 /* Enable load_extension() SQL func */
+#define SQLITE_EnableTrigger 0x00040000 /* True to enable triggers */
+#define SQLITE_DeferFKs 0x00080000 /* Defer all FK constraints */
+#define SQLITE_QueryOnly 0x00100000 /* Disable database changes */
+#define SQLITE_CellSizeCk 0x00200000 /* Check btree cell sizes on load */
+#define SQLITE_Fts3Tokenizer 0x00400000 /* Enable fts3_tokenizer(2) */
+#define SQLITE_EnableQPSG 0x00800000 /* Query Planner Stability Guarantee */
/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace 0x08000000 /* Debug print SQL as it executes */
@@ -1491,6 +1487,12 @@ struct sqlite3 {
#define SQLITE_VdbeEQP 0x80000000 /* Debug EXPLAIN QUERY PLAN */
#endif
+/*
+** Allowed values for sqlite3.mDbFlags
+*/
+#define DBFLAG_SchemaChange 0x0001 /* Uncommitted Hash table changes */
+#define DBFLAG_PreferBuiltin 0x0002 /* Preference to built-in funcs */
+#define DBFLAG_Vacuum 0x0004 /* Currently in a VACUUM */
/*
** Bits of the sqlite3.dbOptFlags field that are used by the
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 341d3f0dc..1b9f91405 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -3882,28 +3882,39 @@ static int SQLITE_TCLAPI md5file_cmd(
const char **argv
){
FILE *in;
+ int ofst;
+ int amt;
MD5Context ctx;
void (*converter)(unsigned char*, char*);
unsigned char digest[16];
char zBuf[10240];
- if( argc!=2 ){
+ if( argc!=2 && argc!=4 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
- " FILENAME\"", (char*)0);
+ " FILENAME [OFFSET AMT]\"", (char*)0);
return TCL_ERROR;
}
+ if( argc==4 ){
+ ofst = atoi(argv[2]);
+ amt = atoi(argv[3]);
+ }else{
+ ofst = 0;
+ amt = 2147483647;
+ }
in = fopen(argv[1],"rb");
if( in==0 ){
Tcl_AppendResult(interp,"unable to open file \"", argv[1],
"\" for reading", (char*)0);
return TCL_ERROR;
}
+ fseek(in, ofst, SEEK_SET);
MD5Init(&ctx);
- for(;;){
+ while( amt>0 ){
int n;
- n = (int)fread(zBuf, 1, sizeof(zBuf), in);
+ n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
if( n<=0 ) break;
MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
+ amt -= n;
}
fclose(in);
MD5Final(digest, &ctx);
diff --git a/src/trigger.c b/src/trigger.c
index dfa094141..2a4fdd8ed 100644
--- a/src/trigger.c
+++ b/src/trigger.c
@@ -585,7 +585,7 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
*pp = (*pp)->pNext;
}
sqlite3DeleteTrigger(db, pTrigger);
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
}
diff --git a/src/vacuum.c b/src/vacuum.c
index 841aa5200..fde08ddc2 100644
--- a/src/vacuum.c
+++ b/src/vacuum.c
@@ -130,7 +130,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
- int saved_flags; /* Saved value of the db->flags */
+ u16 saved_mDbFlags; /* Saved value of db->mDbFlags */
+ u32 saved_flags; /* Saved value of db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
u8 saved_mTrace; /* Saved trace settings */
@@ -153,11 +154,12 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
** restored before returning. Then set the writable-schema flag, and
** disable CHECK and foreign key constraints. */
saved_flags = db->flags;
+ saved_mDbFlags = db->mDbFlags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
- db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
- | SQLITE_PreferBuiltin | SQLITE_Vacuum);
+ db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
+ db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
db->mTrace = 0;
@@ -268,8 +270,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
"WHERE type='table'AND coalesce(rootpage,1)>0",
zDbMain
);
- assert( (db->flags & SQLITE_Vacuum)!=0 );
- db->flags &= ~SQLITE_Vacuum;
+ assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
+ db->mDbFlags &= ~DBFLAG_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy the triggers, views, and virtual tables from the main database
@@ -337,6 +339,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
end_of_vacuum:
/* Restore the original value of db->flags */
db->init.iDb = 0;
+ db->mDbFlags = saved_mDbFlags;
db->flags = saved_flags;
db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange;
diff --git a/src/vdbe.c b/src/vdbe.c
index 3e6231e0d..d9900f383 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -2950,7 +2950,7 @@ case OP_Savepoint: {
int isSchemaChange;
iSavepoint = db->nSavepoint - iSavepoint - 1;
if( p1==SAVEPOINT_ROLLBACK ){
- isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
+ isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0;
for(ii=0; ii<db->nDb; ii++){
rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
SQLITE_ABORT_ROLLBACK,
@@ -2969,7 +2969,7 @@ case OP_Savepoint: {
if( isSchemaChange ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
- db->flags = (db->flags | SQLITE_InternChanges);
+ db->mDbFlags |= DBFLAG_SchemaChange;
}
}
@@ -3249,7 +3249,7 @@ case OP_SetCookie: {
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
pDb->pSchema->schema_cookie = pOp->p3;
- db->flags |= SQLITE_InternChanges;
+ db->mDbFlags |= DBFLAG_SchemaChange;
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
pDb->pSchema->file_format = pOp->p3;
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 599fe7041..d8e47be50 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -189,8 +189,8 @@ struct sqlite3_value {
union MemValue {
double r; /* Real value used when MEM_Real is set in flags */
i64 i; /* Integer value used when MEM_Int is set in flags */
- int nZero; /* Used when bit MEM_Zero is set in flags */
- void *pPtr; /* Pointer when flags=MEM_NULL and eSubtype='p' */
+ int nZero; /* Extra zero bytes when MEM_Zero and MEM_Blob set */
+ const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
FuncDef *pDef; /* Used only when flags==MEM_Agg */
RowSet *pRowSet; /* Used only when flags==MEM_RowSet */
VdbeFrame *pFrame; /* Used when flags==MEM_Frame */
@@ -222,7 +222,8 @@ struct sqlite3_value {
** representations of the value stored in the Mem struct.
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
-** No other flags may be set in this case.
+** For a pointer type created using sqlite3_bind_pointer() or
+** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
**
** If the MEM_Str flag is set then Mem.z points at a string representation.
** Usually this is encoded in the same unicode encoding as the main
@@ -230,7 +231,7 @@ struct sqlite3_value {
** set, then the string is nul terminated. The MEM_Int and MEM_Real
** flags may coexist with the MEM_Str flag.
*/
-#define MEM_Null 0x0001 /* Value is NULL */
+#define MEM_Null 0x0001 /* Value is NULL (or a pointer) */
#define MEM_Str 0x0002 /* Value is a string */
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
@@ -240,7 +241,7 @@ struct sqlite3_value {
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
-#define MEM_TypeMask 0x81ff /* Mask of type bits */
+#define MEM_TypeMask 0xc1ff /* Mask of type bits */
/* Whenever Mem contains a valid string or blob representation, one of
@@ -248,7 +249,7 @@ struct sqlite3_value {
** policy for Mem.z. The MEM_Term flag tells us whether or not the
** string is \000 or \u0000 terminated
*/
-#define MEM_Term 0x0200 /* String rep is nul terminated */
+#define MEM_Term 0x0200 /* String in Mem.z is zero terminated */
#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
#define MEM_Static 0x0800 /* Mem.z points to a static string */
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
@@ -476,7 +477,7 @@ void sqlite3VdbeMemSetInt64(Mem*, i64);
#else
void sqlite3VdbeMemSetDouble(Mem*, double);
#endif
-void sqlite3VdbeMemSetPointer(Mem*, void*, const char*);
+void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
void sqlite3VdbeMemSetNull(Mem*);
void sqlite3VdbeMemSetZeroBlob(Mem*,int);
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 35b194fff..24545e4f1 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -201,12 +201,13 @@ unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
}
void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){
Mem *p = (Mem*)pVal;
- if( p->flags==(MEM_Null|MEM_Subtype|MEM_Term|MEM_Static)
+ if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
+ (MEM_Null|MEM_Term|MEM_Subtype)
&& zPType!=0
&& p->eSubtype=='p'
- && strcmp(p->z, zPType)==0
+ && strcmp(p->u.zPType, zPType)==0
){
- return p->u.pPtr;
+ return (void*)p->z;
}else{
return 0;
}
@@ -389,11 +390,16 @@ void sqlite3_result_null(sqlite3_context *pCtx){
assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
sqlite3VdbeMemSetNull(pCtx->pOut);
}
-void sqlite3_result_pointer(sqlite3_context *pCtx, void *pPtr, const char *zPT){
+void sqlite3_result_pointer(
+ sqlite3_context *pCtx,
+ void *pPtr,
+ const char *zPType,
+ void (*xDestructor)(void*)
+){
Mem *pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
sqlite3VdbeMemSetNull(pOut);
- sqlite3VdbeMemSetPointer(pOut, pPtr, zPT);
+ sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
}
void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
Mem *pOut = pCtx->pOut;
@@ -1398,13 +1404,21 @@ int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
}
return rc;
}
-int sqlite3_bind_pointer(sqlite3_stmt *pStmt, int i, void *pPtr,const char *zT){
+int sqlite3_bind_pointer(
+ sqlite3_stmt *pStmt,
+ int i,
+ void *pPtr,
+ const char *zPTtype,
+ void (*xDestructor)(void*)
+){
int rc;
Vdbe *p = (Vdbe*)pStmt;
rc = vdbeUnbind(p, i);
if( rc==SQLITE_OK ){
- sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zT);
+ sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor);
sqlite3_mutex_leave(p->db->mutex);
+ }else if( xDestructor ){
+ xDestructor(pPtr);
}
return rc;
}
diff --git a/src/vdbemem.c b/src/vdbemem.c
index eac3b9ed3..45b0b38c1 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -27,7 +27,7 @@
*/
int sqlite3VdbeCheckMemInvariants(Mem *p){
/* If MEM_Dyn is set then Mem.xDel!=0.
- ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
+ ** Mem.xDel might not be initialized if MEM_Dyn is clear.
*/
assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
@@ -40,9 +40,34 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){
/* Cannot be both MEM_Int and MEM_Real at the same time */
assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
- /* Cannot be both MEM_Null and some other type */
- assert( (p->flags & MEM_Null)==0 ||
- (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob))==0 );
+ if( p->flags & MEM_Null ){
+ /* Cannot be both MEM_Null and some other type */
+ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
+ |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
+
+ /* If MEM_Null is set, then either the value is a pure NULL (the usual
+ ** case) or it is a pointer set using sqlite3_bind_pointer() or
+ ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be
+ ** set.
+ */
+ if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
+ /* This is a pointer type. There may be a flag to indicate what to
+ ** do with the pointer. */
+ assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
+
+ /* No other bits set */
+ assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
+ |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
+ }else{
+ /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
+ ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
+ }
+ }else{
+ /* The MEM_Cleared bit is only allowed on NULLs */
+ assert( (p->flags & MEM_Cleared)==0 );
+ }
/* The szMalloc field holds the correct memory allocation size */
assert( p->szMalloc==0
@@ -705,18 +730,25 @@ void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
}
}
+/* A no-op destructor */
+static void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); }
+
/*
** Set the value stored in *pMem should already be a NULL.
** Also store a pointer to go with it.
*/
-void sqlite3VdbeMemSetPointer(Mem *pMem, void *pPtr, const char *zPType){
+void sqlite3VdbeMemSetPointer(
+ Mem *pMem,
+ void *pPtr,
+ const char *zPType,
+ void (*xDestructor)(void*)
+){
assert( pMem->flags==MEM_Null );
- if( zPType ){
- pMem->flags = MEM_Null|MEM_Subtype|MEM_Term|MEM_Static;
- pMem->u.pPtr = pPtr;
- pMem->eSubtype = 'p';
- pMem->z = (char*)zPType;
- }
+ pMem->u.zPType = zPType ? zPType : "";
+ pMem->z = pPtr;
+ pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term;
+ pMem->eSubtype = 'p';
+ pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
diff --git a/src/wherecode.c b/src/wherecode.c
index d577f1d3f..528aeec2b 100644
--- a/src/wherecode.c
+++ b/src/wherecode.c
@@ -794,7 +794,7 @@ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
pWalker->eCode = 1;
}else if( pExpr->op==TK_FUNCTION ){
int d1;
- char d2[3];
+ char d2[4];
if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){
pWalker->eCode = 1;
}
diff --git a/src/whereexpr.c b/src/whereexpr.c
index 461c14af1..7a70b5445 100644
--- a/src/whereexpr.c
+++ b/src/whereexpr.c
@@ -199,7 +199,7 @@ static int isLikeOrGlob(
ExprList *pList; /* List of operands to the LIKE operator */
int c; /* One character in z[] */
int cnt; /* Number of non-wildcard prefix characters */
- char wc[3]; /* Wildcard characters */
+ char wc[4]; /* Wildcard characters */
sqlite3 *db = pParse->db; /* Database connection */
sqlite3_value *pVal = 0;
int op; /* Opcode of pRight */
@@ -246,16 +246,44 @@ static int isLikeOrGlob(
return 0;
}
}
+
+ /* Count the number of prefix characters prior to the first wildcard */
cnt = 0;
while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
cnt++;
+ if( c==wc[3] && z[cnt]!=0 ){
+ if( z[cnt++]>0xc0 ) while( (z[cnt]&0xc0)==0x80 ){ cnt++; }
+ }
}
+
+ /* The optimization is possible only if (1) the pattern does not begin
+ ** with a wildcard and if (2) the non-wildcard prefix does not end with
+ ** an (illegal 0xff) character. The second condition is necessary so
+ ** that we can increment the prefix key to find an upper bound for the
+ ** range search.
+ */
if( cnt!=0 && 255!=(u8)z[cnt-1] ){
Expr *pPrefix;
+
+ /* A "complete" match if the pattern ends with "*" or "%" */
*pisComplete = c==wc[0] && z[cnt+1]==0;
+
+ /* Get the pattern prefix. Remove all escapes from the prefix. */
pPrefix = sqlite3Expr(db, TK_STRING, z);
- if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
+ if( pPrefix ){
+ int iFrom, iTo;
+ char *zNew = pPrefix->u.zToken;
+ zNew[cnt] = 0;
+ for(iFrom=iTo=0; iFrom<cnt; iFrom++){
+ if( zNew[iFrom]==wc[3] ) iFrom++;
+ zNew[iTo++] = zNew[iFrom];
+ }
+ zNew[iTo] = 0;
+ }
*ppPrefix = pPrefix;
+
+ /* If the RHS pattern is a bound parameter, make arrangements to
+ ** reprepare the statement when that parameter is rebound */
if( op==TK_VARIABLE ){
Vdbe *v = pParse->pVdbe;
sqlite3VdbeSetVarmask(v, pRight->iColumn);
diff --git a/test/colname.test b/test/colname.test
index e16304d4a..1497fc275 100644
--- a/test/colname.test
+++ b/test/colname.test
@@ -13,7 +13,6 @@
# The focus of this file is testing how SQLite generates the names
# of columns in a result set.
#
-# $Id: colname.test,v 1.7 2009/06/02 15:47:38 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -326,4 +325,58 @@ do_test colname-8.1 {
}
} {123}
+# 2017-07-29: Interaction between column naming and query flattening.
+# For years now, the query flattener has inserted AS clauses on the
+# outer query that were the original SQL text of the column. This caused
+# column-name shifts when the query flattener was enhanced, breaking
+# legacy applications. See https://sqlite.org/src/info/41c27bc0ff1d3135
+# for details.
+#
+# To fix this, the column naming logic was moved ahead of the query
+# flattener so that column names are assigned before the query flattener
+# runs.
+#
+db close
+sqlite3 db :memory:
+do_test colname-9.100 {
+ db eval {
+ CREATE TABLE t1(a,b);
+ INSERT INTO t1 VALUES(1,2);
+ CREATE VIEW v1(x,y) AS SELECT a,b FROM t1;
+ }
+ execsql2 {SELECT v1.x, (Y) FROM v1}
+ # Prior to the fix, this would return: "v1.x 1 (Y) 2"
+} {x 1 y 2}
+do_test colname-9.110 {
+ execsql2 {SELECT * FROM v1}
+} {x 1 y 2}
+do_test colname-9.120 {
+ db eval {
+ CREATE VIEW v2(x,y) AS SELECT a,b FROM t1 LIMIT 10;
+ }
+ execsql2 {SELECT * FROM v2 WHERE 1}
+} {x 1 y 2}
+do_test colname-9.130 {
+ execsql2 {SELECT v2.x, [v2].[y] FROM v2 WHERE 1}
+} {x 1 y 2}
+do_test colname-9.140 {
+ execsql2 {SELECT +x, +y FROM v2 WHERE 1}
+} {+x 1 +y 2}
+
+do_test colname-9.200 {
+ db eval {
+ CREATE TABLE t2(c,d);
+ INSERT INTO t2 VALUES(3,4);
+ CREATE VIEW v3 AS SELECT c AS a, d AS b FROM t2;
+ }
+ execsql2 {SELECT t1.a, v3.a AS n FROM t1 LEFT JOIN v3}
+} {a 1 n 3}
+do_test colname-9.211 {
+ execsql2 {SELECT t1.a AS n, v3.a FROM t1 JOIN v3}
+} {n 1 a 3}
+do_test colname-9.210 {
+ execsql2 {SELECT t1.a, v3.a AS n FROM t1 JOIN v3}
+} {a 1 n 3}
+
+
finish_test
diff --git a/test/like.test b/test/like.test
index bae770b07..1702dde71 100644
--- a/test/like.test
+++ b/test/like.test
@@ -207,7 +207,7 @@ do_test like-3.3.100 {
SELECT x FROM t1 WHERE x LIKE 'abc%' ORDER BY 1;
}
} {abc abcd nosort {} i1}
-do_test like-3.3.101 {
+do_test like-3.3.100.cnt {
set sqlite_like_count
} 0
@@ -1048,4 +1048,52 @@ ifcapable !icu {
} {1}
}
+# As of 2017-07-27 (3.21.0) the LIKE optimization works with ESCAPE as
+# long as the ESCAPE is a single-byte literal.
+#
+db close
+sqlite3 db :memory:
+do_execsql_test like-15.100 {
+ CREATE TABLE t15(x TEXT COLLATE nocase, y, PRIMARY KEY(x));
+ INSERT INTO t15(x,y) VALUES
+ ('abcde',1), ('ab%de',2), ('a_cde',3),
+ ('uvwxy',11),('uvwx%',12),('uvwx_',13),
+ ('_bcde',21),('%bcde',22),
+ ('abcd_',31),('abcd%',32),
+ ('ab%xy',41);
+ SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';
+} {2}
+do_execsql_test like-15.101 {
+ EXPLAIN QUERY PLAN
+ SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '/';
+} {/SEARCH/}
+do_execsql_test like-15.102 {
+ EXPLAIN QUERY PLAN
+ SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '//';
+} {/SCAN/}
+do_execsql_test like-15.103 {
+ EXPLAIN QUERY PLAN
+ SELECT y FROM t15 WHERE x LIKE 'ab/%d%' ESCAPE '';
+} {/SCAN/}
+do_execsql_test like-15.110 {
+ SELECT y FROM t15 WHERE x LIKE 'abcdx%%' ESCAPE 'x';
+} {32}
+do_execsql_test like-15.111 {
+ SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y
+} {2 41}
+do_execsql_test like-15.112 {
+ EXPLAIN QUERY PLAN
+ SELECT y FROM t15 WHERE x LIKE 'abx%%' ESCAPE 'x' ORDER BY +y
+} {/SEARCH/}
+do_execsql_test like-15.120 {
+ SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
+} {22}
+do_execsql_test like-15.121 {
+ EXPLAIN QUERY PLAN
+ SELECT y FROM t15 WHERE x LIKE '/%bc%' ESCAPE '/';
+} {/SEARCH/}
+
+
+
+
finish_test
diff --git a/test/ossfuzz.c b/test/ossfuzz.c
index 51983548b..7b28cf6a7 100644
--- a/test/ossfuzz.c
+++ b/test/ossfuzz.c
@@ -71,6 +71,28 @@ static int progress_handler(void *pClientData) {
#endif
/*
+** Disallow debugging pragmas such as "PRAGMA vdbe_debug" and
+** "PRAGMA parser_trace" since they can dramatically increase the
+** amount of output without actually testing anything useful.
+*/
+static int block_debug_pragmas(
+ void *Notused,
+ int eCode,
+ const char *zArg1,
+ const char *zArg2,
+ const char *zArg3,
+ const char *zArg4
+){
+ if( eCode==SQLITE_PRAGMA
+ && (sqlite3_strnicmp("vdbe_", zArg1, 5)==0
+ || sqlite3_stricmp("parser_trace", zArg1)==0)
+ ){
+ return SQLITE_DENY;
+ }
+ return SQLITE_OK;
+}
+
+/*
** Callback for sqlite3_exec().
*/
static int exec_handler(void *pCnt, int argc, char **argv, char **namev){
@@ -128,6 +150,9 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
sqlite3_db_config(cx.db, SQLITE_DBCONFIG_ENABLE_FKEY, uSelector&1, &rc);
uSelector >>= 1;
+ /* Do not allow debugging pragma statements that might cause excess output */
+ sqlite3_set_authorizer(cx.db, block_debug_pragmas, 0);
+
/* Remaining bits of the selector determine a limit on the number of
** output rows */
execCnt = uSelector + 1;
diff --git a/test/schema6.test b/test/schema6.test
new file mode 100644
index 000000000..7de04d51c
--- /dev/null
+++ b/test/schema6.test
@@ -0,0 +1,163 @@
+# 2017-07-30
+#
+# 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 to show that certain CREATE TABLE statements
+# generate identical database files. For example, changes in identifier
+# names, white-space, and formatting of the CREATE TABLE statement should
+# produce identical table content.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix schema6
+
+# Command: check_same_database_content TESTNAME SQL1 SQL2 SQL3 ...
+#
+# This command creates fresh databases using SQL1 and subsequent arguments
+# and checks to make sure the content of all database files is byte-for-byte
+# identical. Page 1 of the database files is allowed to be different, since
+# page 1 contains the sqlite_master table which is expected to vary.
+#
+proc check_same_database_content {basename args} {
+ set i 0
+ set hash {}
+ foreach sql $args {
+ catch {db close}
+ forcedelete test.db
+ sqlite3 db test.db
+ db eval $sql
+ set pgsz [db one {PRAGMA page_size}]
+ db close
+ set sz [file size test.db]
+ set thishash [md5file test.db $pgsz [expr {$sz-$pgsz}]]
+ if {$i==0} {
+ set hash $thishash
+ } else {
+ do_test $basename-$i "set x $thishash" $hash
+ }
+ incr i
+ }
+}
+
+# Command: check_different_database_content TESTNAME SQL1 SQL2 SQL3 ...
+#
+# This command creates fresh databases using SQL1 and subsequent arguments
+# and checks to make sure the content of all database files is different
+# in ways other than on page 1.
+#
+proc check_different_database_content {basename args} {
+ set i 0
+ set hashes {}
+ foreach sql $args {
+ forcedelete test.db
+ sqlite3 db test.db
+ db eval $sql
+ set pgsz [db one {PRAGMA page_size}]
+ db close
+ set sz [file size test.db]
+ set thishash [md5file test.db $pgsz [expr {$sz-$pgsz}]]
+ set j [lsearch $hashes $thishash]
+ if {$j>=0} {
+ do_test $basename-$i "set x {$i is the same as $j}" "All are different"
+ } else {
+ do_test $basename-$i "set x {All are different}" "All are different"
+ }
+ lappend hashes $thishash
+ incr i
+ }
+}
+
+check_same_database_content 100 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(xyz INTEGER, abc, PRIMARY KEY(xyz), UNIQUE(abc));
+ INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(xyz INTEGER, abc, UNIQUE(abc), PRIMARY KEY(xyz));
+ INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY ASC, b UNIQUE);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ CREATE UNIQUE INDEX t1b ON t1(b);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+ CREATE UNIQUE INDEX t1b ON t1(b);
+}
+
+check_same_database_content 110 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY UNIQUE, b UNIQUE);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE, UNIQUE(a));
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b);
+ CREATE UNIQUE INDEX t1b ON t1(b);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+ CREATE UNIQUE INDEX t1b ON t1(b);
+}
+
+check_same_database_content 120 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE) WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(xyz INTEGER, abc, PRIMARY KEY(xyz), UNIQUE(abc))WITHOUT ROWID;
+ INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(xyz INTEGER, abc, UNIQUE(abc), PRIMARY KEY(xyz))WITHOUT ROWID;
+ INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY ASC, b UNIQUE) WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY UNIQUE, b UNIQUE) WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE) WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE, UNIQUE(a))
+ WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
+ CREATE UNIQUE INDEX t1b ON t1(b);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b) WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+ CREATE UNIQUE INDEX t1b ON t1(b);
+}
+
+check_different_database_content 130 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY UNIQUE, b UNIQUE);
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+} {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE) WITHOUT ROWID;
+ INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...');
+}
+
+
+finish_test
diff --git a/test/without_rowid1.test b/test/without_rowid1.test
index 0c77773ab..c7899cfb3 100644
--- a/test/without_rowid1.test
+++ b/test/without_rowid1.test
@@ -328,5 +328,19 @@ do_catchsql_test 7.3 {
) WITHOUT ROWID;
} {1 {no such column: rowid}}
+# 2017-07-30: OSSFuzz discovered that an extra entry was being
+# added in the sqlite_master table for an "INTEGER PRIMARY KEY UNIQUE"
+# WITHOUT ROWID table. Make sure this has now been fixed.
+#
+db close
+sqlite3 db :memory:
+do_execsql_test 8.1 {
+ CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID;
+ CREATE INDEX t1x ON t1(x);
+ INSERT INTO t1(x,b) VALUES('funny','buffalo');
+ SELECT type, name, '|' FROM sqlite_master;
+} {table t1 | index t1x |}
+
+
finish_test
diff --git a/tool/GetTclKit.bat b/tool/GetTclKit.bat
index 1c9f92bc1..0cc62b3f8 100644
--- a/tool/GetTclKit.bat
+++ b/tool/GetTclKit.bat
@@ -29,6 +29,8 @@ IF DEFINED PROCESSOR (
GOTO usage
)
+SET PROCESSOR=%PROCESSOR:AMD64=x64%
+
%_VECHO% Processor = '%PROCESSOR%'
SET DUMMY2=%2
@@ -193,12 +195,19 @@ ECHO.
GOTO no_errors
:fn_TclKitX86Variables
+ REM
+ REM NOTE: By default, use latest available version of the TclKit SDK
+ REM for x86. However, the "default" TclKit executable for x86
+ REM is still used here because it is the only one "well-known"
+ REM to be available for download.
+ REM
IF NOT DEFINED TCLKIT_PATCHLEVEL (
- SET TCLKIT_PATCHLEVEL=8.6.4
+ SET TCLKIT_PATCHLEVEL=8.6.6
)
SET TCLKIT_VERSION=%TCLKIT_PATCHLEVEL:.=%
SET TCLKIT_VERSION=%TCLKIT_VERSION:~0,2%
- SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
+ REM SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
+ SET TCLKIT_EXE=tclkit-8.6.4.exe
SET TCLKIT_LIB=libtclkit%TCLKIT_PATCHLEVEL:.=%.lib
SET TCLKIT_LIB_STUB=libtclstub%TCLKIT_VERSION:.=%.a
SET TCLKIT_SDK=libtclkit-sdk-x86-%TCLKIT_PATCHLEVEL%
@@ -210,20 +219,19 @@ GOTO no_errors
GOTO :EOF
:fn_TclKitX64Variables
+ REM
+ REM NOTE: By default, use latest available version of the TclKit SDK
+ REM for x64. However, the "default" TclKit executable for x86
+ REM is still used here because it is the only one "well-known"
+ REM to be available for download.
+ REM
IF NOT DEFINED TCLKIT_PATCHLEVEL (
- REM
- REM NOTE: By default, use latest available version of the TclKit SDK
- REM for x64. However, the "default" TclKit executable for x86
- REM is still used here because it is the only one "well-known"
- REM to be available for download.
- REM
- SET TCLKIT_PATCHLEVEL=8.6.3
- SET TCLKIT_EXE=tclkit-8.6.4.exe
- ) ELSE (
- SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
+ SET TCLKIT_PATCHLEVEL=8.6.6
)
SET TCLKIT_VERSION=%TCLKIT_PATCHLEVEL:.=%
SET TCLKIT_VERSION=%TCLKIT_VERSION:~0,2%
+ REM SET TCLKIT_EXE=tclkit-%TCLKIT_PATCHLEVEL%.exe
+ SET TCLKIT_EXE=tclkit-8.6.4.exe
SET TCLKIT_LIB=libtclkit%TCLKIT_PATCHLEVEL:.=%.lib
SET TCLKIT_LIB_STUB=libtclstub%TCLKIT_VERSION:.=%.a
SET TCLKIT_SDK=libtclkit-sdk-x64-%TCLKIT_PATCHLEVEL%