diff options
-rw-r--r-- | VERSION | 2 | ||||
-rw-r--r-- | autoconf/Makefile.msc | 2 | ||||
-rwxr-xr-x | configure | 18 | ||||
-rw-r--r-- | ext/fts3/fts3.c | 2 | ||||
-rw-r--r-- | ext/fts5/fts5_tcl.c | 2 | ||||
-rw-r--r-- | ext/fts5/fts5_test_mi.c | 2 | ||||
-rw-r--r-- | ext/misc/carray.c | 4 | ||||
-rw-r--r-- | ext/rtree/rtree.c | 42 | ||||
-rw-r--r-- | manifest | 81 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/alter.c | 14 | ||||
-rw-r--r-- | src/build.c | 33 | ||||
-rw-r--r-- | src/callback.c | 4 | ||||
-rw-r--r-- | src/func.c | 30 | ||||
-rw-r--r-- | src/insert.c | 14 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/prepare.c | 4 | ||||
-rw-r--r-- | src/select.c | 83 | ||||
-rw-r--r-- | src/sqlite.h.in | 41 | ||||
-rw-r--r-- | src/sqlite3ext.h | 4 | ||||
-rw-r--r-- | src/sqliteInt.h | 28 | ||||
-rw-r--r-- | src/tclsqlite.c | 19 | ||||
-rw-r--r-- | src/trigger.c | 2 | ||||
-rw-r--r-- | src/vacuum.c | 13 | ||||
-rw-r--r-- | src/vdbe.c | 6 | ||||
-rw-r--r-- | src/vdbeInt.h | 15 | ||||
-rw-r--r-- | src/vdbeapi.c | 28 | ||||
-rw-r--r-- | src/vdbemem.c | 54 | ||||
-rw-r--r-- | src/wherecode.c | 2 | ||||
-rw-r--r-- | src/whereexpr.c | 32 | ||||
-rw-r--r-- | test/colname.test | 55 | ||||
-rw-r--r-- | test/like.test | 50 | ||||
-rw-r--r-- | test/ossfuzz.c | 25 | ||||
-rw-r--r-- | test/schema6.test | 163 | ||||
-rw-r--r-- | test/without_rowid1.test | 14 | ||||
-rw-r--r-- | tool/GetTclKit.bat | 32 |
36 files changed, 637 insertions, 291 deletions
@@ -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 @@ -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); } } } @@ -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%
|